1、objc_class内部结构
NSObject对象的数据结构都是存储在objc_class内部的,即objc_class有什么,NSObject以及 我们继承后自定义的对象就有什么
// objc_class继承自objc_object,所以会有一个属性isa
struct objc_class : objc_object {
// Class ISA;
Class superclass; // 指向父类的地址
cache_t cache; // 方法缓存列表
//结构体,内部存储着主要的数据,通过&不同的掩码值获取不同的信息地址
class_data_bits_t bits;
// 获取存放在bits中的可读可写的数据信息
class_rw_t *data() {
return bits.data();
}
......
}
objc_class的主要信息都隐藏在bits中,那么返回后的class_rw_t中存放的是什么呢?
struct class_rw_t {
uint32_t flags;
uint32_t version;
const class_ro_t *ro; // 只读的,Class的初始信息
method_array_t methods; // 方法列表
property_array_t properties; // 属性列表
protocol_array_t protocols; // 协议列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
}
rw_t: read write table 可读可写,说明,后期我们可以向里面添加信息
class_ro_t:read only table 创建类的时候的初始信息
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; // 初始属性列表
......
}
注意:
class_ro_t中的列表都是list_t
class_rw_t中的列表都是array_t,而且class_ro_t中多了一个ivars成员变量列表
思考:
1.class_ro_t 与class_rw_t 之间有什么联系
2.array 与list 有什么区别和联系
2、method_array_t 与 method_list_t
method_array_t里面存放的是 method_list_t数组,所以method_array_t是一个二维数组
method_list_t里面存放是的metod_t 是一维数组
//举例说明 array_t 和list_t的关系
class method_array_t :
// C++的语法,是一种泛型,
// method_array_t里面存放的是method_list_t, 二维数组
//method_list_t 里面存放的是method_t ,一维数组
public list_array_tt<method_t, method_list_t>
{
typedef list_array_tt<method_t, method_list_t> Super;
public:
method_list_t **beginCategoryMethodLists() {
return beginLists();
}
method_list_t **endCategoryMethodLists(Class cls);
method_array_t duplicate() {
return Super::duplicate<method_array_t>();
}
};
同理,property_array_t和protocol_array_t也是存放的对应类型的二维数组
3、method_t
struct method_t {
SEL name; // 方法选择器,也就是方法的名字
const char *types; // 方法的返回类型和参数
MethodListIMP imp; // 方法的存放地址
};
4、总结
1.objc_class内部包含superclass、cache方法缓存列表,bits类的信息
2.bits & 一个掩码值才能获取到内部的数据
3.class_rw_t 是可读可写的,目的是方便以后可以向里面插入新的数据,如分类,在程序运行的时候,会将分类和class_ro_t中的数据按顺序挪放到class_rw_t中,最终可以达到后编译的类方法可以覆盖先编译的类方法
4.class_ro_t 是只读的 ,里面存放的是类的最初的信息
5.method_array_t 是二维数组里面存放的是method_list_t一维数组
6.method_list_t存放的是method_t