iOS底层原理:对象alloc流程分析

索引

  • alloc和init初探
  • 断点找到源码库名称
  • 下载源码库和编译调试
  • 开始探索alloc流程
  • 总结

alloc和init初探

新建一个iOS项目,创建一个PWPerson类,运行如下代码:

    PWPerson *object1 = [PWPerson alloc];
    PWPerson *object2 = [object1 init];
    PWPerson *object3 = [object1 init];
    LGNSLog(@"%@ - %p - %p",object1,object1,&object1);
    LGNSLog(@"%@ - %p - %p",object2,object2,&object2);
    LGNSLog(@"%@ - %p - %p",object3,object3,&object3);

得到的结果是,对象在alloc和init后得到的指针地址是一样的,但是他们的指针的地址又不一样,分别是0x7ffee91840d8、0x7ffee91840d0、0x7ffee91840c8,而且都是相差8个字节。猜测:对象在alloc后就已经完成了内存分配和地址关联。
打印对象alloc和init地址.png

断点找到源码库名称

说明

通过设置断点进入alloc函数,无论如何也只能进入到NSObjec.h文件里定义的alloc函数,根本看不到什么信息。所以我们可以通过下面三种方法,找到Object-C的alloc实现库:

1. 通过下alloc符号断点跟流程查找

直接添加Symbolic Breakpionts断点,输入alloc:

添加alloc Symbolic Breakpoints类型断点.png
先关掉alloc断点,打开[PWPerson alloc]断点然后运行,如图:
设置alloc符号断点查找.png
再打开alloc点,点击Continue program execution按钮继续运行,然后就来到这:
打开设置alloc符号断点运行.png
现在,我们就很明显的看到了libobjc.A.dylib``+[NSObject alloc]:,那么它库名称应该就是objc了,目的已达到。而且我们还看到了一个_objc_rootAlloc,也可以再添加_objc_rootAlloc符号断点进入看看。

2. 通过摁住control点击step into方式进入查找

只设置[PWPerson alloc]断点然后运行,程序到断点停止后摁住键盘的control点击step into进去(断点记下)

摁住control点step into.png
这样,我们就到了这里,看到了objc_alloc,把它添加到Symbolic Breakpoint断点,就会显示对应OC库的名称了:
添加objc_alloc断点.png

3. 查看汇编跟流程查找

首先设置断点调试总是显示汇编模式

调成断点进入汇编模式.png
设置[PWPerson alloc]的断点运行,得到这个,然后在下alloc设置断点在运行:
设置显示汇编模式后运行.png
运行停在红框的位置后,再control点击step into进去就得到
step into汇编.png
看到又和第2个方法一样的了,就可以按着第2个方法添加objc_allocSymbolic Preakpoints断点可以看到库名称。

下载源码库和编译调试

通过上面的查找,我们可以知道OC的alloc实现源码名称应该是objc,然后我们就开始去苹果的开源网站去查找相应的代码库了,进入https://opensource.apple.com/tarballs/往下拉,找到objc4/点击进入,下载最新的objc开源库objc4-781.tar.gz

下载objc最新开源库.png
由于直接下载下来的源码库是不能直接运行调试的,需要额外的配置,具体配置细节推荐大家看这里,Cooci大神的iOS_objc4-756.2 最新源码编译调试

开始探索alloc流程

下载好的objc4-781源码经过一番折腾终于可以运行了。然后就有了接下来的alloc探索之旅了...

objc4-781可以运行了.png

1. 新建一个用来的调试的Target

在objc项目下新建一个Mac的命令行调试Target,取名为PWDebug,如下:

源码工程下新建target.png
图片.png

添加给PWDebug添加objc4的二进制依赖
图片.png

在PWDebug里新建一个PWPerson对象,继承至NSObject。并编码运行看看是否成功
图片.png

设置[PWPerson alloc]断点和Jump Definition到NSObject.mm'给alloc`设置断点
图片.png
图片.png

运行程序停在[PWPerson alloc]后,点击下一步直接就运行结束了,并没有进入到NSObject.mmalloc那里。这下慌了,没有配置好吗???确实是。原因是Xcode 11开始新建Target的Enable Hardened Runtime默认是Yes,把它设置成No就可以了。

图片.png

2. 设置断点调试跟着流程走

通过设置断点跟流程进去得到的流程如下


OC alloc流程分析图.001.jpeg

总结

你可能感兴趣的:(iOS底层原理:对象alloc流程分析)