runtime10 - class内存结构
内存结构
iOS 14 以前:
#define FAST_DATA_MASK 0x00007ffffffffff8UL struct class_data_bits_t { uintptr_t bits; public: class_rw_t* data() { return (class_rw_t *)(bits & FAST_DATA_MASK); } }; /* OC对象 */ struct objc_object { void *isa; }; /* 类对象 */ struct objc_class : objc_object { Class superclass; cache_t cache; class_data_bits_t bits; public: class_rw_t* data() { return bits.data(); } objc_class* metaClass() { return (objc_class *)((long long)isa & ISA_MASK); } }; struct class_ro_t { uint32_t flags; uint32_t instanceStart; uint32_t instanceSize; // instance对象占用的内存空间 #ifdef __LP64__ uint32_t reserved; #endif const uint8_t * ivarLayout; const char * name; // 类名 method_list_t * baseMethodList; protocol_list_t * baseProtocols; const ivar_list_t * ivars; // 成员变量列表 const uint8_t * weakIvarLayout; property_list_t *baseProperties; }; struct class_rw_t { uint32_t flags; uint32_t version; const class_ro_t *ro; method_list_t * methods; // 方法列表 property_list_t *properties; // 属性列表 const protocol_list_t * protocols; // 协议列表 Class firstSubclass; Class nextSiblingClass; char *demangledName; }; 复制代码
iOS 14以后: 针对class_rw_t 做了一些优化
struct class_rw_ext_t { const class_ro_t *ro; method_array_t methods; property_array_t properties; protocol_array_t protocols; char *demangledName; uint32_t version; }; struct class_rw_t { uint32_t flags; uint16_t witness; explicit_atomic<uintptr_t> ro_or_rw_ext; Class firstSubclass; Class nextSiblingClass; } 复制代码
iOS14 以前:
iOS14以后:
优化原因:详细看这里
class_ro_t和class_rw_t的关系与区别
ro指readonly, rw指readwrite
在realizeclass以前, class的bits中放的是class_ro_t的地址,在realizeclass时, 会根据class_ro_t来初始化class_rw_t
编译期能确定下来的信息都在class_ro_t
中, class_ro_t
都是编译过后就不会发生改变的
class_rw_t
中则提供了运行时对类进行扩展的能力, 在运行过程中可能变化, method_array_t / property_array_t / protocol_array_t
这些都是二维数组
在优化后,如果该类没有分类, 没有在运行时添加方法等,class_rw_t
的ro_or_rw_ext
成员有可能指向的是class_ro_t
的地址
作者:潘森
链接:https://juejin.cn/post/7028115401124888589