一.首先我们看一下alloc与init的探索
1.源码跟调试方法
我们经常用allon init,但是他们的本质都是什么呢,我们想要知道他们的本质,首先要通过源码和断点调试,我们需要一份最新的源码objc4-781官方源码。
最新macOS 10.15下objc4-779.1源码编译调试
下面我们来介绍调试方法,有三种调试方法
(1)下符号断点直接跟流程
加符号断点 添加断点名称(2)执行到断点处,按住control 点击step into
点击step into 进入方法 找到所在库(3)执行到断点处,汇编查找跟流程
汇编方式找到objc_alloc方法,step into进入方法内部查看所在库的位置
汇编代码2.alloc跟init分别都做了什么,我们来看个例子
alloc&init从打印可看出 alloc开辟了内存空间,而init并未对内存空间做任何处理。
二.探索alloc的流程图
1.alloc方法
alloc2._objc_rootAlloc方法
_objc_rootAlloc3.callAlloc方法
callAlloc4. _objc_rootAllocWithZone方法
_objc_rootAllocWithZone5. _class_createInstanceFromZone方法
_class_createInstanceFromZone6. alloc核心流程 cls->instanceSize && calloc && obj-> initInstanceIsa
(1)cls->instanceSize 计算内存空间大小
首先判断是否有缓存,有的话采用字节对齐方法计算所需内存大小
如果没有缓存,则计算内存大小,如果size 小于 16,最小取16
fastInstanceSize方法:快速计算内存大小方法
fastInstanceSize方法align16方法:内存对齐方法
alingn16内存对齐算法:
假设传入的参数: x = 8
x + size_t(15) = 8 + 15 = 23
x + size_t(15) 二进制表示:
0000 0000 0001 0111= 23
size_t(15) 二进制 表示:
0000 0000 0000 1111= 15
~size_t(15) 取反为:
1111 1111 1111 0000
x + size_t(15) & ~size_t(15):0000 0000 0001 0000= 16
返回值 (x + size_t(15)) & ~size_t(15) = 16 也就是 16 的倍数对齐,即 16 字节对齐
(2)calloc 申请开辟内存空间
(3)cls->instanceSize 类和指针地址绑定到一起,关联到相应的类
到这里alloc的流程就结束了。
最后附上alloc流程图
alloc流程图
网友评论