OC -- 对象的alloc流程分析

360 阅读2分钟

在日常开发中,我们经常会使用到 alloc,但是重来也不会去探究它的底层实现原理. 今天我们就来分析一下 alloc 底层实现原理.

首先我们先准备 苹果objc源码objc源码编译 .

  1. 查看alloc底层原理的几种方式
  1. 结合符号断点定位 在 Symbolic Breakpoint 中添加一个 objc_alloc 的符号断点,然后就可以看 objc 动态库的底层方法. 添加符号断点 2.png

  2. 通过汇编跟踪流程(当前使用比较多)

先在 alloc 处添加断点, 然后通过汇编跟踪流程, 再通过符号断点(objc_alloc) image.png image.png (Debug -> Debug Workflow -> Always Show Disassembly)

  1. 通过已知符号断点,确定未知

在 Symbolic Breakpoint 中添加一个 alloc 的符号断点. 但是这个方法有一个缺点,alloc这个符号断点会比较多,因为系统中和我们自己的代码中会有很多地方调用alloc这个方法 image.png image.png

  1. 后期继续补充...

alloc探索

在 Xcode 中打开下载好的 苹果objc源码,然后搜索 alloc { image.png 然后依次进入 _objc_rootAlloc --> callAlloc image.png 那么问题来了,这里是先执行 _objc_rootAllocWithZone 还是先执行 objc_msgSend 呢? 如果!cls->ISA()->hasCustomAWZ()成立! 就会先执行 _objc_rootAllocWithZone,然后再执行objc_msgSend。 那么我们依次给 _objc_rootAlloccallAlloc_objc_rootAllocWithZone添加符号断点

注意:这里有一个小问题,需要在执行 DGPerson * p1 = [DGPerson alloc]; 断点前关闭符号断点!

可以看到是流程是: _objc_rootAlloc -> _objc_rootAllocWithZone -> objc_msgSend image.png

流程图

image.png

  1. 底层方法的编译和调试

1.底层编译器优化

首先在 main.m 中添加如下代码, 添加断点,并且运行. image.png

然后再打开汇编查看汇编代码 (Debug -> Debug Workflow -> Always Show Disassembly) image.png 我们在 Build Settings 中搜索 Optimization Level 设置编译器优化等级 image.png image.png 不知道 Optimization Level 的同学可以点击查看 Optimization Level 的相关解释.

我们再次运行程序,发现汇编代码比设置Optimization Level之前少了很多. 这就是编译器优化! image.png