前言
作为个iOS开发者,开发过程中常用到对象的初始化和创建,也就是对象的alloc init。但我们有没有去探索过alloc这个过程,底层是如何执行的呢?现在我们一起探索一下alloc底层原理。
示例代码用于打印三个对象的地址,内存地址,和指针地址


从打印结果中我们发现三个对象内存地址一样,说明三个对象指向的内存中同一块内存地址,但指针地址有差异。探索alloc内部执行,我们有三种方式:1、通过卡断点查看汇编代码,2、卡断点通过xcode 按住control + step into 进入查看 ,3、通过加符号断点的。下面通过加符号断点举例说明
1、先打断点,让程序断在alloc的位置

2、加符号断点 alloc


以上流程可以发现objc_alloc在libobjc.A.dylib这个库里面。
源码探索
1、在确保objc源码编译能通过的情况下,创建一个对象,按住command点击并进入查看源码


2、点击查看_objc_rootAlloc源码实现

3、点击查看callAlloc源码实现

在这一步程序会将最有可能执行的分支告诉编译器,其主要目的是编译器对程序进行优化。fastpath定义中__builtin_expect((x),1)表示 x 的值为真的可能性更大,执行 if 里面语句的可能性也更大。slowpath定义中的__builtin_expect((x),0)表示 x 的值为假的可能性更大,执行 else 里面语句的可能性也更大。cls->ISA()->hasCustomAWZ()主要判断是否自定义了allocWithZone。
4、点击查看_objc_rootAllocWithZone源码实现

5、点击查看_class_createInstanceFromZone源码实现

此处代码为alloc核心代码,注意点️size=cls->instanceSize(extraBytes) 为计算需要开辟多少内存空间。️obj=(id)calloc(1,size)为开辟内存的方式。️obj->initInstanceIsa(cls,hasCxxDtor)为将对象与内存地址绑定。

以上为开辟内存时,计算所需内存大小核心代码,内存大小由成员变量决定,计算字节采用16字节对齐的方式。
总结
通过以上alloc执行流程的探究,可以得到alloc流程图如下

网友评论