内存结构
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
的地址