iOS 底层原理之 alloc 探究

465 阅读3分钟

前言

我们日常开发经常会用到alloc和init方法。那么这两个方法究竟都干了什么?有什么区别?接下来,我们深入的探索!

先看个例子

1.png

2.png 通过打印的log可以看出:
obj和obj1的内容、指向的内存地址一样,但是指针的内存地址不一样。
obj2和obj、obj1的内容、指向的内存地址、指针的内存地址都不一样。
大概可以得出结论:alloc方法开辟了内存。init方法好像什么都没做。那么真的是这样吗?接下来开始探索alloc的底层实现。

如何查找要分析的方法在哪个系统类库下

OC在Xcode中是没有开源的这个大家都知道,但是苹果还是为大家开源了一些类库。可以用通过这个链接下载到源码。opensource.apple.com/tarballs/
那么如何分析、定位alloc方法具体是在哪个类库中实现的呢?这里提供3种方法。

方法1

先断点到需要定位的代码行。然后打符号断点,捕捉alloc方法。打完符号断点后向下执行。这时候发现了调用的系统库。

3.png

4.png

5.png

方法2

第二种 先断点到需要定位的代码行。然后按住control键,step into进入到汇编。然后发现了调用的方法,这时候给发现的方法打符号断点。打完符号断点后向下执行。这时候发现了调用的系统库。

6.png

7.png

8.png

方法3

第三种 先断点到需要定位的代码行。然后点击菜单栏里的Debug->Debug Workflow->Always Show Disassembly进入汇编寻找方法。按住control键,然后step into一步一步找调用的方法。然后再用符号断点的方法找到系统库.

9.png

10.png

11.png

如何用源码分析

找到了需要探索分析的类库。下载之后却无法直接编译调试。可以参考一些大牛的文章来配置、也可以去GitHub上下载可编译调试的源码。 github.com/LGCooci/obj…

alloc源码探索

打开源码工程,哇,太复杂了。别慌,全局搜索alloc { 进行定位。

12.png 发现里面调用了_objc_rootAlloc方法,继续进入。

13.png 发现里面调用了callAlloc方法,继续进入。

14.png 这里就稍微有点复杂了,但是没关系。因为我们运行了源码,打断点跟着看看进入哪个方法就行了。结果发现进入了_objc_rootAllocWithZone方法,一样点进入看看。

15.png 没什么好说的继续进入。此时进入了最核心的代码部分。

16.png

自己打上断点,在控制台一步一步输出变量,你大概就会发现每句代码的作用了。
这个方法里主要做了3件事:
cls->instanceSize(extraBytes);计算内存空间
(id)calloc(1, size);开辟内存空间并且返回指针
obj->initInstanceIsa(cls, hasCxxDtor);初始化指针并且和类关联起来

总结

alloc方法的作用主要就是开辟内存空间,关联指针和类。
init方法没有开辟内存空间的作用。它的作用相当于一个构造方法,一个接口。让开发者可以初始化出自己想要的对象。

`