+initialize方法

1.initialize方法调用
  • +initialize方法会在类第一次接收到消息时调用
  • 本质通过objc_msgSend(cls, SEL_initialize)进行调用
  • +initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点:
  1. 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
  2. 如果分类实现了+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("");
}

你可能感兴趣的:(+initialize方法)