对象结构体
//对象结构体(包含实例对象/类对象/元类对象)
//实例对象isa指向类对象,类对象isa指向元类对象,元类对象isa指向根对象
struct objc_object {
isa_t isa;//isa结构体
Class ISA();//没有优化过的isa
Class getIsa();//优化过的isa
}
union isa_t
{
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;//指向类对象/元类对象
uintptr_t bits;
struct {
uintptr_t nonpointer : 1;//是否指针优化
uintptr_t has_assoc : 1;//是否有关联对象
uintptr_t has_cxx_dtor : 1;//是否有析构函数
uintptr_t shiftcls : 33; //实例对象的地址
uintptr_t magic : 6;//
uintptr_t weakly_referenced : 1;//是否有弱引用引用
uintptr_t deallocating : 1;//对象正在释放
uintptr_t has_sidetable_rc : 1;//是否使用了引用计数表
uintptr_t extra_rc : 19;//当前对象的引用计数-1
};
};
对象的初始化
inline void objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
initIsa(cls, true, hasCxxDtor);
}
inline void objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor)
{
if (!nonpointer) {
isa.cls = cls;
} else {
isa.bits = ISA_MAGIC_VALUE;
isa.has_cxx_dtor = hasCxxDtor;
isa.shiftcls = (uintptr_t)cls >> 3;
}
}
类对象结构体
//类对象结构体,继承objc_object,固含有isa指针
struct objc_class : objc_object {
Class superclass;//父类
cache_t cache;//缓存
class_data_bits_t bits; //类的信息存储
class_rw_t *data() {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
}
类对象信息存储结构体
//class_data_bits_t通过按位与运算获取class_rw_t
class_rw_t* data() {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
//方法列表等信息,可以被Runtime扩展
struct class_rw_t {
class_ro_t *ro;//类的原始数据
method_array_t methods;//方法列表数组
property_array_t properties;//属性列表数组
protocol_array_t protocols;//协议列表数组
}
//类的原始信息,不可修改
struct class_ro_t {
method_list_t * baseMethodList;//原始方法列表
protocol_list_t * baseProtocols;//原始属性列表
ivar_list_t * ivars;//原始成员变量列表
}
类对象缓存结构体
//从缓存cache_t中查找bucket_t
struct cache_t {
struct bucket_t *_buckets;
mask_t _mask;
mask_t _occupied;
};
//bucket中包含方法的key(@selector)和IMP
struct bucket_t {
cache_key_t _key;
IMP _imp;
};
一些基本元素结构体
//方法结构体
struct method_t {
SEL name;//方法名
const char *types;//方法入值参数和返回值参数
IMP imp;//方法存储地址,也是函数地址
};
//成员变量结构体
struct ivar_t {
int32_t *offset;
const char *name;//名字
const char *type;//类型
uint32_t alignment_raw;
uint32_t size;
};