在日常开发中,我们经常会使用到 alloc,但是重来也不会去探究它的底层实现原理. 今天我们就来分析一下 alloc 底层实现原理.
- 查看alloc底层原理的几种方式
-
结合符号断点定位 在 Symbolic Breakpoint 中添加一个 objc_alloc 的符号断点,然后就可以看 objc 动态库的底层方法.
-
通过汇编跟踪流程(当前使用比较多)
先在 alloc 处添加断点, 然后通过汇编跟踪流程, 再通过符号断点(objc_alloc)
(Debug -> Debug Workflow -> Always Show Disassembly)
- 通过已知符号断点,确定未知
在 Symbolic Breakpoint 中添加一个 alloc 的符号断点.
但是这个方法有一个缺点,alloc这个符号断点会比较多,因为系统中和我们自己的代码中会有很多地方调用alloc这个方法
- 后期继续补充...
alloc探索
在 Xcode 中打开下载好的 苹果objc源码,然后搜索 alloc {
然后依次进入
_objc_rootAlloc --> callAlloc
那么问题来了,这里是先执行
_objc_rootAllocWithZone 还是先执行 objc_msgSend 呢?
如果!cls->ISA()->hasCustomAWZ()成立! 就会先执行 _objc_rootAllocWithZone,然后再执行objc_msgSend。
那么我们依次给 _objc_rootAlloc、callAlloc、_objc_rootAllocWithZone添加符号断点
注意:这里有一个小问题,需要在执行 DGPerson * p1 = [DGPerson alloc]; 断点前关闭符号断点!
可以看到是流程是: _objc_rootAlloc -> _objc_rootAllocWithZone -> objc_msgSend
流程图
- 底层方法的编译和调试
1.底层编译器优化
首先在 main.m 中添加如下代码, 添加断点,并且运行.
然后再打开汇编查看汇编代码 (Debug -> Debug Workflow -> Always Show Disassembly)
我们在
Build Settings 中搜索 Optimization Level 设置编译器优化等级
不知道 Optimization Level 的同学可以点击查看 Optimization Level 的相关解释.
我们再次运行程序,发现汇编代码比设置Optimization Level之前少了很多. 这就是编译器优化!