在内存中它本质上是一个 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 对象时,你实际上是握着一个指向数据段某块固定内存的指针。这块内存里整齐地排列着这个类的家族树、最近调用的方法缓存以及一份详尽的“功能清单”(方法、属性)。