OC底层原理03 - NSObject的alloc 源码分析
2020-11-23 本文已影响0人
H雷610
在上篇文章我们探究了自定义类
的alloc
源码,但是[NSObject alloc]
和[自定义类 alloc]
的源码流程是否一致呢?如果不一致那具体又是哪里不同呢?这就是我们需要探究分析的。
分析NSObject的alloc流程
发现问题
- 在main函数是增加一个
NSObject
对象的定义,并在对象处加上断点。
image.png 运行程序,将会停在断点处,即将开始执行[NSObject alloc]
。 - 根据自定义类的alloc流程分析,知道第一步应该是进入
alloc
方法,即在alloc
方法处加上断点。
image.png - 继续执行代码,但此时发现并未在断点处停下,而是直接走完了整个程序,这是为什么呢?
跟踪NSObject alloc的流程
接下来我们开启汇编调试:Debug --> Debug Workflow --> 勾选 Always Show Disassemly
,只保留mian
函数中的断点,其他均关闭或删除,运行工程,通过汇编可以发现NSObject
并没有走alloc
源码,而是走的objc_alloc
objc_alloc
,在objc_alloc
中加一个断点,先暂时关闭image.png 运行程序,断点断在
NSObject *objc = [NSObject alloc]
打开objc_alloc
处的断点,继续执行,发现会进入objc_alloc
的源码,此时查看cls
是NSObject
image.png 跳转至
callAlloc
的源码image.png 由于
NSObject
没有自定义的allocWithZone
方法,cls->ISA()->hasCustomAWZ()
为0,因此会进入_objc_rootAllocWithZone
方法。在
_objc_rootAllocWithZone
方法中,跟自定义对象的alloc
流程一致,完成alloc的重要三步骤:
-
cls -> instanceSize
-> 计算需要开辟的内存空间大小 -
calloc
-> 申请内存 -
obj -> initInstanceIsa
-> 将申请的内存与isa关联
alloc
调用流程
image.png
总结
[NSObject alloc]
流程与[HLPerson alloc]
流程在cls->ISA()->hasCustomAWZ()
判断前一致,但是由于HLPerson
类重写了NSObject
中的alloc
方法,cls->ISA()->hasCustomAWZ()
这个判断的结果与NSObject
结果不一样。NSObject
类直接去完成alloc
的重要三步骤,而HLPerson
类需要通过sel
找到alloc
方法的编号后再执行alloc
方法。