前言
作为个iOS开发者,开发过程中常用到对象的初始化和创建,也就是对象的alloc init。但我们有没有去探索过alloc这个过程,底层是如何执行的呢?现在我们一起探索一下alloc底层原理。
示例代码用于打印三个对象的地址,内存地址,和指针地址
从打印结果中我们发现三个对象内存地址一样,说明三个对象指向的内存中同一块内存地址,但指针地址有差异。探索
alloc内部执行,我们有三种方式:
- 通过卡断点查看汇编代码
- 卡断点通过
xcode按住control + step into进入查看 - 通过加
符号断点的。 下面通过加符号断点举例说明
1、先打断点,让程序断在alloc的位置
2、加符号断点
alloc
以上流程可以发现
objc_alloc在libobjc.A.dylib这个库里面。
源码探索
可以去苹果开源网站去下载objc源码进行研究了
- 在确保
objc源码编译能通过的情况下,创建一个对象,按住command点击并进入查看源码 - 点击查看
_objc_rootAlloc源码实现 - 点击查看
callAlloc源码实现在这一步程序会将最有可能执行的分支告诉编译器,其主要目的是编译器对程序进行优化。
fastpath定义中__builtin_expect((x),1)表示x的值为真的可能性更大,执行if里面语句的可能性也更大。slowpath定义中的__builtin_expect((x),0)表示x的值为假的可能性更大,执行else里面语句的可能性也更大。cls->ISA()->hasCustomAWZ()主要判断是否自定义了allocWithZone。 - 点击查看
_objc_rootAllocWithZone源码实现 - 点击查看
_class_createInstanceFromZone源码实现此处代码为
alloc核心代码,注意点️size=cls->instanceSize(extraBytes)为计算需要开辟多少内存空间。️obj=(id)calloc(1,size)为开辟内存的方式。️obj->initInstanceIsa(cls,hasCxxDtor)为将对象与内存地址绑定。以上为开辟内存时,计算所需内存大小核心代码,内存大小由成员变量决定,计算字节采用
16字节对齐的方式。
总结
通过以上alloc执行流程的探究,可以得到alloc流程图如下