探究oc底层必须去苹果开源的网站下载Objc源码
下载大家可以从 此处下载到objc源码 但是下载下来是不能用的。需要进行一系列配置,我个人是从github上面找到的配置好的,避免在上面浪费特别多的时间
同时也要将这个开关打开,进行汇编层面的分析。
alloc
首先创建一个OC类,并执行alloc方法
打断点进入汇编
由此可以得出oc里面的初始化是由objc_msgsend向类发送alloc消息
他的定义为
objc_msgSend(id 消息接受者,sel 发送消息)
进行发送的从汇编进入objc_msg_send可以输入regiter read
添加一个 symbol “alloc”断点
点击下一步 可以看到断点进入了 libobjc.A.dylib
由此我们查找的文档应该是libobjc,看到跳入的方法为 _objc_rootAlloc
打开NSObject的c++文件,查看_objc_rootAlloc的方法构成,同时也继续走断点 走入了objc_rootAlloc:
将断点进入 _class_createInstance方法看到,并将断点打到他的返回值的地方
由此可见_class_createInstaceFromZone 创建了实例对象
那么既然alloc已经生成这个对象了为什么还要执行init呢,下面继续分析
init
开启进入汇编的模式
objcmsgsend向Person发送了ini条消息 那个指针是init但是没有标识出来。
电脑太卡了调试不过去总之他就是走到NSObject的init方法
可以看到init方法 将self穿进去然后又将其返回,可以看到他将我们传回去的obj又返回来了,可以看出来他其实什么也没做,苹果这么做的原因是为了让子类重写时可以返回响应的obj做初始化其他的参数。根据自己的需求返回自己想要的obj
总结
objc alloc流程是
- 调用alloc方法
- objcmsgsend(class,alloc) 调用_objc_rootAlloc
- 调用callAlloc
- 调用class_createInstance
- 调用_class_createInstanceFromZone
- 最终得到了响应类型的对象
objc init
init初始化其实是一个_objc_rootInit获得他自身,这样设计的主要原因是可以让子类重写这个方法然后根据需求得到想要的对象