美文网首页
NSObject的alloc探索

NSObject的alloc探索

作者: lkm_0bdc | 来源:发表于2020-09-09 18:20 被阅读0次

    上一篇我们进行了alloc源码的探索,这次我们紧接之前的内容,继续探索NSObject的alloc和自定义alloc的区别,以及NSObject为什么不走源码工程。

    NSObject为什么不走源码工程

    • 在objc4—781可编译源码中的main函数同时在NSObject和LGPerson打上断点。


    • 然后跳转到alloc源码打一个断点,运行的时候需要关闭。


    • 跳转objc_alloc打一个断点,运行的时候需要关闭。


    在运行,断点定位到NSObject部分,打开alloc源码断点和objc_alloc断点,继续执行会发现NSObject和LGPerson都调用入objc_alloc源码。

    让我们继续探索NSObject的alloc现象以及LGPerson走两次的现象

    • NSObject 是iOS中的基类,所有自定义的类都需要继承自NSObject
    • LGPerson 是继承自NSObject类的,重写了NSObject中的alloc方法

    通过汇编我们都可以发现NSObject和LGPerson都调用objc_alloc源码,但是我们会存在疑惑

    • NSObject只走objc_alloc源码
    • LGPerson会走两次(alloc -> objc_alloc)

    通过汇编Debug --> Debug Workflow --> 勾选 Always Show Disassemly
    关闭之前的的断点,只留下main函数的断点,可以发现NSObject和LGPerson都是调用objc_alloc源码


    继续在main函数LGPerson的位置打一个断点,跳转到objc_alloc源码,可以看到cls是NSArray,NSArray的父类是NSObject,在callocAlloc源码中,流程是和继承子类一样的,它就向系统发送alloc方法,但是NSArray没有alloc方法,因此开始向系统发送消息,去查找找到父类进行一系列的初始化即NSObject的alloc方法早就在系统级别就做完了。



    所以由上述调试过程可以得出,LGPerson走两次的原因是首先需要去查找sel,以及对应的imp的关系,当前需要查找的是 alloc 的方法编号,但是为什么会找到objc_alloc?,这就是系统方面做的一些逻辑判断,接下来,让我们一起看看系统做了什么。

    NSObject中的alloc走objc_alloc的原因

    需要下载一份LLVM源码,进行探索

    • 在llvm源码中搜索objc_alloc


    • 搜索omf_alloc:找到tryGenerateSpecializedMessageSend,表示尝试生成特殊消息发送,这里就调用了objc_objc的逻辑,其中的关键代码是EmitObjCAlloc。


    • 跳转EmitObjCAlloc的定义可以看到alloc 的处理是调用了 objc_alloc


    由此可以得出 NSObject中的alloc 会走到 objc_alloc,这部分是由系统级别的消息处理逻辑,所以NSObject的初始化是由系统完成的,因此也不会走到alloc的源码工程中。

    相关文章

      网友评论

          本文标题:NSObject的alloc探索

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