1.initialize方法调用
- +initialize方法会在类第一次接收到消息时调用
- 本质通过objc_msgSend(cls, SEL_initialize)进行调用
- +initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点:
- 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
- 如果分类实现了+initialize,就覆盖类本身的+initialize调用
[YHObject alloc];
[YHObject alloc];
[YHObject alloc];
[YHObject alloc];
YHObject的initialize会被调用一次
调用objc_msgSend(),肯定会去寻找方法的IMP,就是下面的方法
IMP lookUpImpOrForward(Class cls, SEL sel, id inst,
bool initialize, bool cache, bool resolver)
{
...
// Check for +initialize
if (initialize && !cls->isInitialized()) {
_class_initialize (_class_getNonMetaClass(cls, inst));
}
...
}
// 如果是需要初始化,并且没有初始化则调用
void _class_initialize(Class cls)
{
...
Class supercls;
// 如果存在父类则先对父类进行初始化
// See note about deadlock above.
supercls = cls->superclass;
if (supercls && !supercls->isInitialized()) {
_class_initialize(supercls);
}
callInitialize(cls);
...
}
// 最后调用
void callInitialize(Class cls)
{
((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize);
asm("");
}
网友评论