首先上源码,苹果源码的地址 当然也可以直接参照cooci 老师的博客掘金地址,以及可以直接调试的objc的源码
- 引入正题之前先介绍三种下符号断点的方式
-
先打一个断点,此时在断点处停下,然后按住control
此时点击step in,就会进入汇编
-
通过add symbolic breakpoint
点击symbolic breakpoint,添加符号断点,再次debug
-
打开汇编,always show disassembly
- 有了符号断点的知识,后面终于进入整体了,我们先不要直接看源码,可以直接先通过下符号断点的方式,看底层alloc 的流程. 关于这个流程,alloc的调用如下图
但是对比源码,以为流程图画错了,
在我们加载类的时候会看到里面有这么一个方法
fixupMessageRef
此时进入这个方法看下
会看到这个方法里面做了一些关于SEL 和IMP 绑定的修正:
alloc 的IMP指向的是_objc_alloc. 是不是此时一切就豁然开朗啦,原来SEL alloc实际的实现是_objc_alloc.
同时我们来查看下llvm 的源码
发现当mac os 10.10 之后都会将SEL
alloc的IMP指向objc_alloc.
apple 会在底层对alloc 方法进行拦截, alloc 会标记成objc_alloc
因此也解释了为什么
call_alloc会调用两次的原因。第一次是因为apple 拦截了alloc方法并进行标记objc_alloc, 执行到objc_alloc之后,在调用objc_messageSend 发送了一个alloc的消息,由于第一次已经被标记了,所以第二次调用alloc, 会走alloc正常的流程。