class_ro_t  /  class_rw_t  /  class_rw_ext_t
objc4 · 三者关系、生命周期与内存优化
生命周期 — 什么时候创建
① COMPILE TIME
class_ro_t 诞生
编译器写入二进制
存在 __DATA_CONST 段
内存只读,永不修改
每个类必然存在
② LOAD TIME · realizeClass()
class_rw_t 诞生
首次使用类时懒创建
heap 上分配
ro_or_rwe → class_ro_t
每个类必然存在
③ RUNTIME · 按需创建
class_rw_ext_t 诞生
Category 附加时创建
或运行时修改方法时
合并 category 方法列表
~10% 的类才会创建
④ NEVER
未修改的类
纯系统类 / 无 Category
class_rw_t 直接指向 ro
不创建 rwe,节省内存
≈ 90% 的类走这条路
三个结构体的字段
class_ro_t
只读 · 编译期
uint32_t flags
RO_META / RO_ROOT / RO_HAS_CXX_STRUCTORS 等
uint32_t instanceStart
实例变量起始偏移(继承链对齐用)
uint32_t instanceSize
实例字节大小(alloc 的依据)
method_list_t * baseMethods
编译期方法列表,不含 category
protocol_list_t * baseProtocols
编译期协议列表
ivar_list_t * ivars
实例变量列表,运行时不可增删
uint8_t * weakIvarLayout
弱引用变量的内存布局
property_list_t * baseProperties
编译期属性列表
const char * name
类名字符串
存于 __DATA_CONST,只读保护
class_rw_t
可读写 · 运行时
uint32_t flags
RW_REALIZED / RW_INITIALIZING 等运行时标志
uint16_t witness
并发安全版本号,用于检测 rwe 是否已创建
uintptr_t ro_or_rwe
核心字段:低1位=0指向ro,低1位=1指向rwe
Class firstSubclass
子类链表头节点
Class nextSiblingClass
兄弟类链表,用于遍历类层级
methods() / properties() / protocols()
↳ 从 rwe 或 ro 取,调用方无感知
heap 分配,每次 realizeClass 时创建
class_rw_ext_t
按需 · ~10%
const class_ro_t * ro
始终指向编译期 ro,不变
method_array_t methods
合并后的完整方法列表(含 category)
property_array_t properties
合并后的完整属性列表
protocol_ref_array_t protocols
合并后的完整协议列表
char * demangledName
Swift 类名解码后的 ObjC 名
uint32_t version
类版本号
Category 附加 / method_setImplementation
↳ 触发创建,方法列表在这里合并

ro_or_rwe — 核心指针的三种状态
未实现(before realizeClass)
bits 直接存的是 class_ro_t*
低位 bit 用作区分标志

bits = (class_ro_t* | flag)
data() 检测标志后返回 ro
已实现,无 rwe
class_rw_t 已分配
ro_or_rwe 低位 = 0

ro_or_rwe → class_ro_t
≈ 90% 的类停在这里
已实现,有 rwe
class_rw_ext_t 已分配
ro_or_rwe 低位 = 1

ro_or_rwe → class_rw_ext_t
rwe 内部再持有 ro 指针

完整指针链 — 从 objc_class 到 ivars
路径 A:无 rwe(绝大多数类)
objc_class.bits
.data()
class_rw_t
ro_or_rwe (低位=0)
class_ro_t
.ivars / .baseMethods
ivar_list_t / method_list_t
路径 B:有 rwe(附加了 Category 的类)
objc_class.bits
.data()
class_rw_t
ro_or_rwe (低位=1)
class_rw_ext_t
.ro → class_ro_t
.methods → 合并方法列表

为什么要拆出 rwe — WWDC 2020 内存优化
旧方案(objc4-781 之前)
class_ro_t
class_rw_t(全部类)
每个类都分配 class_rw_t
含完整 methods / props / protos
典型 App ≈ 30MB 用于 rw
新方案(objc4-781+)
class_ro_t
class_rw_t(精简,无 methods)
rwe(仅10%)
rw 不再存方法列表,只存指针
90% 的类不创建 rwe
节省 ≈ 14MB(Apple 数据)