isa 指针与类结构
问题
ObjC 对象的 isa 指针是什么?类对象和元类的关系?
答案
对象的本质
所有 ObjC 对象本质都是 C 结构体:
// objc_object 结构
struct objc_object {
isa_t isa; // 指向类对象
};
// objc_class 继承自 objc_object
struct objc_class : objc_object {
Class superclass;
cache_t cache; // 方法缓存
class_data_bits_t bits; // 方法列表、属性列表...
};
isa 指向关系
- 实例对象 的 isa → 类对象(存储实例方法)
- 类对象 的 isa → 元类(存储类方法)
- 根元类 的 isa → 自身
nonpointer isa(ARM64 优化)
64 位系统不需要全部 64 位存地址,Apple 利用多余位存储额外信息:
| 位 | 内容 |
|---|---|
| 0 | nonpointer 标志 |
| 1 | has_assoc 有关联对象 |
| 2 | has_cxx_dtor 有 C++ 析构 |
| 3-35 | shiftcls 类指针(33位) |
| 36-41 | magic |
| 42 | weakly_referenced |
| 45 | has_sidetable_rc |
| 46-63 | extra_rc(引用计数 - 1) |
常见面试问题
Q1: 一个 NSObject 对象占多少内存?
答案:NSObject 实例只有一个 isa 指针,理论 8 字节。但 Apple 内存分配最小 16 字节对齐(malloc_size 返回 16)。
Q2: 类方法存在哪里?
答案:类方法存在元类的方法列表中。调用 [NSObject alloc] 时,通过 NSObject 类对象的 isa 找到元类,在元类的方法列表中查找 alloc。