1、objc_object、objc_class、class_rw_t、class_ro_t、cache_t、bucket_t、method_t、protocol_t、ivar_t、property_t
- objc_class 结构体继承自objc_object
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
struct objc_class : objc_object {
// Class ISA;
Class superclass; // objc_class类型的指针,指向父类的objc_class结构体
cache_t cache; // 方法缓存,可增量扩展的哈希表
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
}
// 用散列表缓存调用过的方法,提高方法查询速度
struct cache_t {
struct bucket_t *_buckets; // 可变长度的结构体数组
mask_t _mask; // 散列表长度 - 1
mask_t _occupied; // 已经缓存的方法数量(散列表形式存在,会空槽)
}
typedef uintptr_t cache_key_t;
using MethodCacheIMP = IMP;
struct bucket_t {
MethodCacheIMP _imp; // IMP
cache_key_t _key; // SEL
}
class_rw_t = class_data_bits_t & FAST_DATA_MASK;
struct class_rw_t {
const class_ro_t *ro; // 编译时就确定好的
method_array_t methods; // 方法列表 二维数组
property_array_t properties; // 属性列表 二维数组
protocol_array_t protocols; // 协议列表 二维数组
char *demangledName; // 类名
}
struct class_ro_t {
uint32_t instanceSize; // 长度
const char * name; // 类名
method_list_t * baseMethodList; // 方法列表 一维数组
protocol_list_t * baseProtocols; // 协议 一维数组
const ivar_list_t * ivars; // 成员变量 一维数组
property_list_t *baseProperties; // 属性 一维数组
};
struct method_t {
SEL name; // 方法名
const char *types; // 函数参数 + 返回值类型
MethodListIMP imp; // 方法地址
}
struct protocol_t : objc_object {
const char *mangledName; // 协议名
struct protocol_list_t *protocols; // 协议列表
method_list_t *instanceMethods; // 实例方法
method_list_t *classMethods; // 类方法
method_list_t *optionalInstanceMethods; // 可选实例方法
method_list_t *optionalClassMethods; // 可选类方法
property_list_t *instanceProperties; // 实例属性
property_list_t *_classProperties; // 类属性
const char *demangledName();
}
struct ivar_t {
int32_t *offset; // 地址中的偏移
const char *name; // 变量名
const char *type; // 变量类型
};
struct property_t {
const char *name; // 属性名
const char *attributes; // 属性内容:strong、weak...
};
- 编译后class_data_bits_t 指向的是一个class_ro_t的地址(只读),运行时,通过realizeClass()函数将bits指向class_rw_t
- 初始化类:realizeClass -> 设置rw、ro
// 初始化类信息
static Class realizeClass(Class cls) {
const class_ro_t *ro;
class_rw_t *rw;
Class supercls;
Class metacls;
bool isMeta;
// 是否为空
if (!cls) return nil;
// 是否已经初始化
if (cls->isRealized()) return cls;
assert(cls == remapClass(cls));
// 取出class中的data
ro = (const class_ro_t *)cls->data();
if (ro->flags & RO_FUTURE) {
// class初始化
rw = cls->data();
ro = cls->data()->ro;
cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);
} else {
// 创建class_rw_t
rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
// 给class_rw_t里面的class_ro_t赋值
rw->ro = ro;
// 设置状态
rw->flags = RW_REALIZED|RW_REALIZING;
// 给cls->data重新赋值class_rw_t
cls->setData(rw);
}
isMeta = ro->flags & RO_META;
rw->version = isMeta ? 7 : 0; // old runtime went up to 6
supercls = realizeClass(remapClass(cls->superclass));
metacls = realizeClass(remapClass(cls->ISA()));
cls->superclass = supercls;
cls->initClassIsa(metacls);
cls->setInstanceSize(ro->instanceSize);
if (supercls) {
addSubclass(supercls, cls);
} else {
addRootClass(cls);
}
// 取出class_ro_t中的数据,赋值给class_rw_t
methodizeClass(cls);
return cls;
}
- 初始化类后,class_rw_t中的methods、protocols、properties的都是空的,需要在methodizeClass函数中进行赋值,将class_ro_t中的数据取出,赋值给class_rw_t
// 给rw赋值method list、protocol list、property list
static void methodizeClass(Class cls) {
bool isMeta = cls->isMetaClass();
auto rw = cls->data();
auto ro = rw->ro;
// Install methods and properties that the class implements itself.
// 1、把ro中的方法添加到rw中
method_list_t *list = ro->baseMethods();
if (list) {
prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
rw->methods.attachLists(&list, 1);
}
// 2、把ro中的属性添加到rw中
property_list_t *proplist = ro->baseProperties;
if (proplist) {
rw->properties.attachLists(&proplist, 1);
}
// 3、把ro中的协议添加到rw中
protocol_list_t *protolist = ro->baseProtocols;
if (protolist) {
rw->protocols.attachLists(&protolist, 1);
}
if (cls->isRootMetaclass()) {
addMethod(cls, SEL_initialize, (IMP)&objc_noop_imp, "", NO);
}
// Attach categories.
// 把分类中的方法、属性、协议添加到类中去
category_list *cats = unattachedCategoriesForClass(cls, true /*realizing*/);
attachCategories(cls, cats, false /*don't flush caches*/);
if (cats) free(cats);
}
网友评论