类结构体的定义
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
class_rw_t *data() {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
......
};
-
isa
是指向元类的指针,不了解元类的可以看 Classes and Metaclasses -
super_class
指向当前类的父类 -
cache
用于缓存指针和vtable
,加速方法的调用 -
bits
就是存储类的方法、属性、遵循的协议等信息的地方
class_data_bits_t
其中只含有一个 64 位的 bits 用于存储与类有关的信息。结构体中的注释写到 class_data_bits_t
相当于 class_rw_t
指针加上 rr/alloc
的标志。
它为我们提供了便捷方法用于返回其中的 class_rw_t * 指针:
class_rw_t* data() {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
将 bits
与 FAST_DATA_MASK
进行位运算,只取其中的 [3, 47] 位转换成 class_rw_t *
返回。
在 x86_64 架构上, Mac OS 只使用了其中的 47 位来为对象分配地址。而且由于地址要按字节在内存中按字节对齐,所以掩码的后三位都是 0 。
因为 class_rw_t *
指针只存于第 [3, 47] 位,所以可以使用最后三位来存储关于当前类的其他信息。
#define FAST_IS_SWIFT (1UL<<0)
#define FAST_HAS_DEFAULT_RR (1UL<<1)
#define FAST_REQUIRES_RAW_ISA (1UL<<2)
#define FAST_DATA_MASK 0x00007ffffffffff8UL
- isSwift()
FAST_IS_SWIFT
用于判断 Swift 类 - hasDefaultRR()
FAST_HAS_DEFAULT_RR
当前类或者父类含有默认的方法 - requiresRawIsa()
FAST_REQUIRES_RAW_ISA
当前类的实例需要 raw isa
class_rw_t
在 objc-runtim-new.h 文件中,源码如下:
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_array_t methods;
property_array_t properties;
protocol_array_t protocols;
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
......
};
rw
即 readwrite,内部信息可读可写的。内部包含的信息来源是 runtime 时动态添加的,比如分类中的方法会在运行时添加到method_array_t
中。
class_rw_t
中包括:
-
method_array_t
方法数组 -
property_array_t
属性数组 -
protocol_array_t
协议数组
class_ro_t
在 objc-runtim-new.h 文件中,源码如下:
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#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;
method_list_t *baseMethods() const {
return baseMethodList;
}
};
ro
即 readonly 内部信息只读。内部为类编译器生成的信息,不可添加和删除。
class_ro_t
中包括:
-
name
类名 -
method_list_t
方法列表 -
property_list_t
属性列表 -
protocol_list_t
代理列表 -
ivar_list_t
成员变量列表