问题: 简述iOS的 struct objc_class 的结构.
问题: 简述iOS的 Class对象 的底层结构.
注: 本问题回答基于 objc4-818.2 版本
-
objc_class结构体继承于objc_object结构体,objc_object结构体有且只有一个isa指针.
-
objc_class 含有一个 Class类型的 superclass成员变量.
-
objc_class 含有一个 cache_t类型的 cache成员变量,主要作用是方法缓存.
-
objc_class 含有一个 class_data_bits_t类型的 bits.
struct objc_object {
Class isa;
};
struct objc_class: objc_object {
Class superclass;
cache_t cache;
class_data_bits_t bits;
...
};
通过 class_data_bits_t 的 data()
函数可以获得class_rw_t的结构体,函数内部主要与FAST_DATA_MASK
宏进行了一次与运算.如下所示.
#define FAST_DATA_MASK 0x00007ffffffffff8UL
struct class_data_bits_t {
uintprt_t bits;
...
public:
class_rw_t* data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
...
};
在 读写的列表 class_rw_t
结构体中主要含有一下内容.
注:在最新的objc818.2的代码结构,已经把相关成员变量实现已经直接修改为函数.相关成员变量已经存在了 class_rw_ext_t
的结构体中了.
-
返回值为只读的
class_ro_t
类型的ro()
函数. -
返回值为
method_array_t
的method()
函数. -
返回值为
property_array_t
的properties()
函数. -
返回值为
protocol_array_t
的protocols()
函数.
struct class_rw_ext_t {
DECLARE_AUTHED_PTR_TEMPLATE(class_ro_t)
class_ro_t_authed_ptr<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;
...
private:
using ro_or_rw_ext_t = objc::PointerUnion<const class_ro_t, class_rw_ext_t, PTRAUTH_STR("class_ro_t"), PTRAUTH_STR("class_rw_ext_t")>;
const ro_or_rw_ext_t get_ro_or_rwe() const {
return ro_or_rw_ext_t{ro_or_rw_ext};
}
public:
const class_ro_t* ro() const {
auto v = get_ro_or_rwe();
if (slowpath(v.is<class_rw_ext_t *>())) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->ro;
}
return v.get<const class_ro_t *>(&ro_or_rw_ext);
}
const method_array_t method() const {
auto v = get_ro_or_rwe();
if(v.is<class_rw_ext_t *>()) {
return v.get<const class_rw_ext_t *>(&ro_or_rw_ext)->method;
} else {
return method_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext_t)->baseMethods()};
}
}
const property_array_t properties() const {
auto v = get_ro_or_rw_rwe();
if(v.is<class_rw_ext_t *>()) {
return v.get<const class_rw_ext_t *>(&ro_or_rw_ext)->properties;
} else {
return method_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext_t)->baseProperties};
}
}
const protocol_array_t protocols() const {
auto v = get_ro_or_rw_rwe();
if(v.is<class_rw_ext_t *>()) {
return v.get<const class_rw_ext_t *>(&ro_or_rw_ext)->protocols;
} else {
return method_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext_t)->baseProtocols};
}
}
};
相比于 struct class_rw_t
, struct class_ro_t
主要存储的是以下内容.
-
成员变量的大小信息 - instanceSize.
-
类名 - name.
-
方法列表 baseMethodList.
-
协议列表 baseProtocols.
-
成员变量列表 ivars.
-
属性列表信息 basePropreties.
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#ifdef __LP64__
uint32_t reserved;
#endif
explicit_atomic<const char *> name; // 类名
void *baseMethodList;
protocol_array_t *baseProtocols;
const ivar_list_t *ivars;
property_array_t *baseProperties;
}
Comments | 0 条评论