iOS底层原理-alloc、init 探索

本文主要探索alloc的底层实现原理

  • 大家可以通过 Apple source 在 路径自行下载objc4-781 源码

首先我们有一个疑问,那就是alloc是如何创建对象,开辟内存,并且将对象与内存关联起来的呢?我们带着这些问题打开源码来一探究竟。

  • 1.首先根据main函数中的LGPerson类的alloc方法进入alloc方法的源码实现(即源码分析开始)
    image.png

    2.跳转至_objc_rootAlloc底层实现
    image.png

3.跳转至callAlloc

image.png

4.接下来流程会走到callAlloc的具体实现

image.png

5.进入_class_createInstanceFromZone源码

image.png

这里展示了三个重点方法:
1.cls->instanceSize计算内存大小
2.calloc开辟内存方式
3.obj->initInstanceIsa isa与类绑定在一起

由此可得出alloc的流程图如下

image.png
问题一:系统是如何计算内存空间大小的,即instanceSize的源码流程
  • 跳转到instanceSize源码实现如下图,流程接下来会走进下图标识处

    image.png

  • 跳转至函数fastInstanceSize的源码实现如图

    image.png

  • align16源码实现

    image.png

  • align16算法解读如下图:其中x为一个对象,所占内存8字节

    image.png

此算法说明:由此图看出,与上之后后四位全部抹零了,也就是说保留了16的倍数,16以下全部抹零。由此得出结论,此算法的目的就是16字节对齐。

为什么要16字节对齐?

  • 内存对齐是在计算机中排列数据、访问数据的一种格式,简单来说就是前面的地址必须是后面的地址正数倍,不是就补齐,系统在读取内存的时候,不会随时改变自己读取的长度,这么做的目的是为了节约性能,方便读取。
  • 首先我们知道任何对象都具备一个isa 的属性(isa是一个结构体指针占8字节) ,假设一个对象没有属性,没有内存的情况下,就已经占了8字节,如果按照8字节对齐方式进行存储时会发现对象是一个挨着一个的,前一个对象挨着后一个对象isa,这样就容易导致一些访问错误、野指针的问题出现。为了使整个内存更加安全,所以预留了一些位置。
    到此我们了解了alloc的源码实现,那么init又做了什么呢?

init原理

  • 查看init源码实现


    image.png

    image.png

说明init只返回了self,什么也没有做,那么 init 有什么作用呢?
这里是利用了工厂设计模式, init 的作用是方便子类自定义重写,预留自定义内容的接口,给子类自由发挥的空间。比如array和普通的一个对象,初始化之后,所具有的东西是不一样的,根据用户的需要,可以定制化开发。给开发人员提供一个构造方法的入口。

new

  • 进入new的源码实现可看到如下图:


    image.png

newcallAllocinit的结合,等同于[alloc init],如果子类不想自定义重写的话,直接可以用new进行初始化开辟内存。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容