1-12.【OC】【基础】如果你拿到一个 Class 对象,它在内存中本质上是什么?

6 阅读2分钟

在内存中它本质上是一个 objc_class 结构体

虽然在 Objective-C 层面它看起来是一个神秘的“类”,但在 C 语言底层,它是一个有着固定格式的、存储了该类所有“配置信息”的单例结构体


1. 底层物理结构

根据 Objective-C Runtime 源码(以 objc-runtime-new.h 为准),Class 的本质是这样的:

C++

struct objc_class : objc_object {
    Class superclass;        // 父类类对象
    cache_t cache;           // 方法缓存(性能优化的核心)
    class_data_bits_t bits;  // 具体的类信息(方法、属性、协议等)
};

我们可以把这个结构体拆解为四个关键零件:

第一部分:继承链 (superclass)

占 8 字节。记录了它的父类是谁。当一个方法在当前类找不到时,Runtime 就会沿着这个指针去父类里搜。

第二部分:快速通道 (cache)

占 16 字节。这是为了解决 Smalltalk 消息传递效率低下的关键。 它存储了最近被调用过的方法。当你调用 [obj method] 时,Runtime 会先在这个 cache 里进行哈希查找。如果命中了,直接跳转执行,不需要去查那个庞大的方法表。

第三部分:核心数据 (bits)

这是类的“资料库”。通过一个掩码(Mask)运算,可以从 bits 中取出一个指向 class_rw_t(read-write)或 class_ro_t(read-only)的指针。


2. 深入 bits:类到底长什么样?

通过 bits 提取出来的结构体里,才是你定义的那些代码:

  • Method List: 你写的 -(void)doSomething 的实现地址。
  • Property List: 你定义的 @property
  • Protocol List: 该类遵循的协议。
  • Ivars: 成员变量的定义(注意:实例变量的值存在 Instance 里,变量的定义存在这里)。

3. “类”也是一个对象

注意代码中的第一行:struct objc_class : objc_object。 这意味着 Class 本质上也是一个对象

  • 既然它是对象,它就有 isa 指针。
  • 类对象的 isa 指向哪里?指向 元类(Meta Class)
  • 元类里存什么?存的是你的 类方法 (+ 方法)

4. 内存中的位置

  • 实例对象:通常分配在**堆(Heap)**区。
  • 类对象:在程序启动加载二进制文件(Image)时,由 Runtime 创建并存放在数据段(Data Segment) 。它在整个程序运行期间永远不会被销毁。

总结

当你手里握着一个 Class 对象时,你实际上是握着一个指向数据段某块固定内存的指针。这块内存里整齐地排列着这个类的家族树、最近调用的方法缓存以及一份详尽的“功能清单”(方法、属性)。