iOS底层之alloc探索

449 阅读2分钟

前序

alloc使我们iOS开发者最常用的初始化对象的方法了,那么我们是否对alloc底层做了什么有了解呢?本文我们就来探索下alloc的底层实现。

alloc探究

代码探究

LGPerson *person1 = [LGPerson alloc];
        LGPerson *person2 = [person1 init];
        LGPerson *person3 = [person1 init];

        NSLog(@"对象:\n%@\n%@\n%@\n",person1,person2,person3);
        NSLog(@"对象地址:\n%p\n%p\n%p\n",person1,person2,person3);
        NSLog(@"对象指针地址:\n%p\n%p\n%p\n",&person1,&person2,&person3);

打印结果:

2020-09-09 11:35:27.072554+0800 KCObjc[94267:2603966] 对象:
<LGPerson: 0x101320ec0>
<LGPerson: 0x101320ec0>
<LGPerson: 0x101320ec0>

2020-09-09 11:35:27.073109+0800 KCObjc[94267:2603966] 对象地址:
0x101320ec0
0x101320ec0
0x101320ec0

2020-09-09 11:35:27.073203+0800 KCObjc[94267:2603966] 对象指针地址:
0x7ffeefbff4d0
0x7ffeefbff4c0
0x7ffeefbff4c8

从上面我们发现,person1、person2、person3无论对象以及对象地址都是一样的,唯一不一样的是指向对象的指针地址不同。那么alloc内部到底实现了什么?我们通过源码来分析探究。

源码分析

  • alloc调用_objc_rootAlloc方法

  • callAlloc调用_objc_rootAllocWithZone

  • _objc_rootAllocWithZone调用_class_createInstanceFromZone

  • _class_createInstanceFromZone调用instanceSize方法获得开辟内存空间的大小

    instanceSize方法返回的大小是以16字节对齐,返回的是16的倍数

  • 通过instanceSize方法获得开辟空间大小后通过calloc方法开辟空间

  • calloc开辟空间后通过clsinitInstanceIsa绑定对应的类,比如此处的LGPerson类

      此处的cls就是LGPerson

alloc方法底层流程

init方法是干什么的

init方法是工厂方法,它没有实际的意义,主要是为了方便我们自定义初始化方法的,比如定义initWithXXX的方法

new与alloc init的关系

使用new初始化对象,会进入

从上图中我们点击callAlloc方法进入

方法,此时跟alloc没有什么区别了,因此我们可以总结new相当于alloc + init