探索准备

下载并编译成功源码objc4-750

开始调试

源码配置完成,新建两个类,例如Person类,来断点调试追踪alloc的流程;
屏幕快照 2020-03-17 16.04.04.png
Tips:要等到断点来到当前[Person alloc]的时候在开启alloc方法内的流程追踪,因为系统在创建Person之前会有初始化许多系统类,都会走alloc。
点进去alloc,断点跟上_objc_rootAlloc
屏幕快照 2020-03-17 17.41.20.png
继续jump
屏幕快照 2020-03-17 17.42.26.png
上边两个全断点跟上,会发现一个有意思的事情。
[Person alloc]常规来说是应该进去_objc_rootAlloc,但是没有,而是进入了 objc_alloc 这个简单说下[Person alloc] 调用方法的本质就是通过sel-imp对应去找alloc这个函数实现,但是苹果在这里动了点手脚,当第一次调用alloc的时候,苹果将这个绑定到了objc_alloc,有大神说是为了hook,我目前还不知道以后懂了再说,好,继续走向callAlloc(cls,true,false),设置一堆断点,发现,他直接干到底
屏幕快照 2020-03-17 17.46.00.png
到最后,通过[cls alloc] 来调起我们的_objc_rootAlloc,接下来就乖乖的走_objc_rootAlloc —-> callAlloc(cls,false,true) —-> class_createInstance(cls,0),以上就创建了实例的对象。具体流程细节,稍后补充。

alloc、init和new

alloc()就已经创建了Person实例对象,那么init()干了点啥,实际上init()什么也没干,就是一个工厂设计模式,为了方便他的继承者初始化方法一类的操作。而[Person new]实际上就等价于[[Person alloc]init]
源码点进去一看便知:
屏幕快照 2020-03-17 17.56.38.png
[Person new]的方法调用
屏幕快照 2020-03-17 17.55.41.png