- class_rw_t里面的methods、properties、protocols是二维数组,是可读可写的,包含了类的初始内容、分类的内容
- class_ro_t里面的baseMethodList、baseProtocols、ivars、baseProperties是一维数组,是只读的,包含了类的初始内容
然后看下方法的结构1
2
3
4
5
6struct method_t{
SEL name; // 方法名
const char *types; // 参数和返回类型encode
IMP imp; // 函数指针
};
typedef struct method_t *Method;
看下class_rw_t methods 的初始化, class_ro_t 的结构在编译期间已经决定,无法更改1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31static Class realizeClass(Class cls){
const class_ro_t *ro = (const class_ro_t *)cls->data();
class_rw_t *rw;
if(ro->flags & RO_FUTERE){
// rw已经分配好了
rw = cls->data();
ro = cls->data()->ro;
cls->changeInfo(RW_REALIZED|RW_REALIZING,RW_FUTURE);
}else{
// 未初始化
rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
rw->ro = ro;
rw->flags = RW_REALIZED|RW_REALIZING;
cls->setData(rw);
}
// 其它的一些初始化
// Attach categories
methodizeClass(cls);
}
static void methodizeClass(Class cls){
// 将ro中的基本方法添加到rw中去
method_list_t *list = cls->data()->ro->baseMethods();
prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
cls->data()->methods.attachLists(&list, 1);
// 初始化属性、协议和分类
}
向类动态添加方法
class_addMethod
这个函数可以在运行期对类动态添加方法,我们来看下是怎么实现的:
1 | BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types){ |
向一个类中添加新方法,cls->data()->methods.attachLists(&newlist, 1),仍然是添加到class_rw_t.methods列表中。