返回

关于 alloc 的其他技术细节

IOS

iOS 底层探索之 alloc(下)

导言

iOS 底层探索之 alloc(上) 中,我们深入探讨了对象 alloc 的底层流程,本篇将继续探究 isa 关联对象的流程,以及 isa_t(NONPOINTER_ISA)的数据结构。

isa 关联对象的流程

关联对象查找

当我们调用 alloc 方法时,会先在关联对象表(class_ro_t 中的 ivars 列表)中查找是否有 isa 关联对象。如果找到,则使用该关联对象的地址作为 isa 指针。

关联对象创建

如果关联对象表中没有找到 isa 关联对象,则会创建一个新的关联对象。创建流程如下:

  1. 分配内存空间
  2. 初始化 isa 关联对象,包括 isa 指针(指向类对象)和引用计数(初始值为 1)

关联对象插入

创建好 isa 关联对象后,将其插入关联对象表中。插入位置为 ivars 列表的第一个元素。

isa 指针设置

最后,将创建好的 isa 关联对象的地址赋值给 isa 指针。

isa_t(NONPOINTER_ISA)数据结构

当我们使用非指针类型的 isa 时,会使用 isa_t(NONPOINTER_ISA)数据结构。isa_t 结构体定义如下:

typedef struct isa_t {
    struct isa_t       *cls_isa;    /* isa of its class object */
    uint32_t       bits;         /* bits for this class */
    uint32_t       vtable_index;  /* vtable index */
} isa_t;

其中:

  • cls_isa: 指向其类对象的 isa 指针
  • bits: 存储该类的元数据信息
  • vtable_index: 指向虚方法表的索引

cls_isa 字段指向其类对象的 isa 指针,通过它可以获得该类的元数据信息。bits 字段存储该类的元数据信息,包括:

  • NSObjectFlags: 对象标志位,例如是否被释放等
  • hasWeakReferences: 是否包含弱引用
  • specialClassKind: 特殊类种类,例如元类
  • userInfo: 用户自定义数据

vtable_index 字段指向虚方法表的索引,虚方法表存储着该类的所有虚方法实现。

总结

本文深入分析了 iOS 底层 alloc 过程中 isa 关联对象的流程和 isa_t(NONPOINTER_ISA)数据结构。通过对这些底层细节的理解,我们可以更深入地了解对象的创建过程。

补充内容

除了本文提到的内容外,alloc 还有其他一些技术细节值得关注:

  • 非指针 isa 的优化: 对于非指针 isa,系统会使用一种特殊的优化技术,称为 “Compact ISA”,它可以显著提高内存访问效率。
  • 延迟 isa 关联: 在某些情况下,系统会延迟创建 isa 关联对象,直到首次调用该对象的某个方法时才创建。这是一种性能优化技术,可以减少不必要的内存分配。
  • zone 分配: alloc 方法可以指定一个 zone 参数,它用于指定内存分配的区域。这可以帮助管理内存,并优化应用程序性能。