Runtime03 Method

  • class_rw_t里面的methods、properties、protocols是二维数组,是可读可写的,包含了类的初始内容、分类的内容

  • class_ro_t里面的baseMethodList、baseProtocols、ivars、baseProperties是一维数组,是只读的,包含了类的初始内容



然后看下方法的结构

1
2
3
4
5
6
struct 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
31
static 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
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
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types){
return !addMethod(cls, name, imp, types ?:"", NO);
}

static IMP addMethod(Class cls, SEL name, IMP imp, const char *types, bool replace){
method_t *m;
IMP result;
if((m = getMethodNoSuper_nolock(cls, name)){
// 已经存在这个方法
if(!replace){
result = m->imp;
}else{
result = _method_setImplementation(cls, m, imp); // 重新设置imp
}
}else{
// 添加方法
method_list_t *newlist = (method_list_t *)calloc(sizeof(*newlist), 1);
newlist->first.name = name;
newlist->first.types = types;
newlist->first.imp = imp;
prepareMethodsLists(cls, &newlist, 1, NO, NO);
cls->data()->methods.attachLists(&newlist, 1);
flushCaches(cls);

result = nil;
}

return resul;
}

向一个类中添加新方法,cls->data()->methods.attachLists(&newlist, 1),仍然是添加到class_rw_t.methods列表中。



-------------The End-------------

本文标题:Runtime03 Method

文章作者:kysonyangs

发布时间:2018年06月23日 - 18:06

最后更新:2020年05月17日 - 16:05

原始链接:https://kysonyangs.github.io/default/Runtime03_Method/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。