探究+initialize本质

作者: 我是C | 来源:发表于2018-08-20 20:26 被阅读113次

    记录于此!

    1.代码层面验证
    2.阅读源码

    一、代码


    image.png

    推导:
    1.只导入头文件,不会调用+initialize
    2.第一次发消息时候调用+initialize,不发消息不会调用

    二、源码

    1.objc-initialize.mm文件
    2.callInitialize方法
    3.callInitialize方法 向上找到 _class_initialize方法
    4.全局搜索_class_initialize方法,在objc-runtime-new.mm文件 ,发现lookUpImpOrForward方法
    5.lookUpImpOrForward 方法 向上找到 _class_lookupMethodAndLoadCache3方法
    6.全局搜索_class_lookupMethodAndLoadCache3方法,然后在objc-msg-arm64.s汇编文件中发现了bl __class_lookupMethodAndLoadCache3 汇编语句
    7.发现bl __class_lookupMethodAndLoadCache3 汇编语句objc_msgSend(objc_msgSend 是用汇编来实现的,为了效率)

    以上是查找源码的顺序,其实不难发现:
    · initialize是通过objc_msgSend调用
    ** 区分+load 方法,+load 是直接调用函数,而+initialize是消息发送机制

    删减部分源码查看:

    IMP lookUpImpOrForward(Class cls, SEL sel, id inst, 
                           bool initialize, bool cache, bool resolver)
    {
        if (initialize  &&  !cls->isInitialized()) {
            runtimeLock.unlockRead();
            _class_initialize (_class_getNonMetaClass(cls, inst));
            runtimeLock.read();
            // If sel == initialize, _class_initialize will send +initialize and 
            // then the messenger will send +initialize again after this 
            // procedure finishes. Of course, if this is not being called 
            // from the messenger then it won't happen. 2778172
        }
    }
    

    判断是否需要初始化initialize 且 该类没有被初始化过,然后进入_class_initialize 方法,同样只保留精华代码。

    void _class_initialize(Class cls)
    {
        supercls = cls->superclass;
        if (supercls  &&  !supercls->isInitialized()) {
            _class_initialize(supercls);
        }
        callInitialize(cls);
    }
    

    递归调用,先调用父类,然后调用子类

    总结:

    1.第一次发消息时候调用+initialize,不发消息不会调用
    2.+initialize 会先调用父类,然后调用子类的
    3.每一个类只会initialize一次(父类的initialize方法可能会被调用多次,因为是消息发送机制,因为如果子类没有实现+initialize,会调用父类的+initialize)
    4.类别中的+initialize会覆盖类中的+initialize(消息机制,多个类别实现执行最后一个)

    相关文章

      网友评论

        本文标题:探究+initialize本质

        本文链接:https://www.haomeiwen.com/subject/itlliftx.html