OC底层原理01:alloc方法底层探索

objc源码

alloc的源码,须要去苹果的Source Browser下载最新的版本.markdown

能够参考源码编译调试,直接在源码基础上跑起来,方便查看OC方法的底层实现步骤.app


alloc

alloc方法,能够说是最多见的类方法,在咱们建立类对象时,是不可避免要使用到alloc,有人可能要质疑了,new不能够建立类对象吗? 但其实new方法,仍是会调用到alloc.oop

  • 那么,alloc都作了什么?

有过iOS开发基础的都知道,alloc init方法,会为要建立的对象,开辟一段内存空间并初始化类对象.那咱们来看下图.post

由上图咱们看到,p一、p二、p3所指向的内存空间都是相同的,也就说明,只有alloc方法会去开辟空间,init方法没有对开辟的内存进行过修改spa

  • 再深刻探索如下:alloc是如何开辟空间的呢?

经过下载的objc源码,以及源码编译调试中的搭建,咱们能够直接点进去看到alloc的源码实现过程. 3d

重点_class_createInstanceFromZone


其中关键的三个步骤:指针

    1. size = cls->instanceSize(extraBytes);

1.1. cache.fastInstanceSize(extraBytes) 调试

1.2. align16 code

// 其中`_flags`来自与当前类的标识,由_flags的不一样,得出不一样的结果,这里咱们获得`size = 16`.
size_t size = _flags & FAST_CACHE_ALLOC_MASK;
// extra传进来的是0, FAST_CACHE_ALLOC_DELTA16=8 则align16(8)
// align16方法 主要作的事情是16字节对齐,而如今iOS版本要求的就是16字节对齐
// 缘由在于对象的isa指针占据8字节,若是按照8字节对齐方式,多个对象的isa连续排列,容易形成访问异常
// 因此最终return了 “16”, 即size = cls->instanceSize(extraBytes) = 16.
return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);

复制代码

    1. obj = (id)calloc(1, size);

这个方法,会开辟size个字节的内存区域,返回obj是指向这块内存的指针.orm


    1. obj->initInstanceIsa(cls, hasCxxDtor);

这个方法会将开辟的内存关联到要建立的类对象.

总结:

alloc方法要作的事情为

  1. 由系统计算出开辟的内存空间大小
  2. 申请开辟得出的大小内存空间,获得isa指针
  3. 将开辟的内存空间与要建立的类对象进行关联


init

init方法都作了什么?

由源码咱们能够看到,init方法只是返回了alloc获得的obj地址,因此开头案例,p一、p二、p3指向的指针都是相同的.


new

new的底层调用了callALloc,是上边alloc建立过程当中的其中一个方法.

可是咱们要在合适的地方使用new方法,由于它的弊端是,它没有办法调用重写自定义的init方法.

相关文章
相关标签/搜索