1、objc_class內(nèi)部結(jié)構(gòu)
NSObject對象的數(shù)據(jù)結(jié)構(gòu)都是存儲在objc_class內(nèi)部的保屯,即objc_class有什么,NSObject以及 我們繼承后自定義的對象就有什么
// objc_class繼承自objc_object,所以會有一個(gè)屬性isa
struct objc_class : objc_object {
// Class ISA;
Class superclass; // 指向父類的地址
cache_t cache; // 方法緩存列表
//結(jié)構(gòu)體塞帐,內(nèi)部存儲著主要的數(shù)據(jù)燎悍,通過&不同的掩碼值獲取不同的信息地址
class_data_bits_t bits;
// 獲取存放在bits中的可讀可寫的數(shù)據(jù)信息
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; // 協(xié)議列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
}
rw_t: read write table 可讀可寫奖地,說明橄唬,后期我們可以向里面添加信息
class_ro_t:read only table 創(chuàng)建類的時(shí)候的初始信息
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; // 初始協(xié)議列表
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中多了一個(gè)ivars成員變量列表
思考:
1.class_ro_t 與class_rw_t 之間有什么聯(lián)系
2.array 與list 有什么區(qū)別和聯(lián)系
2赋焕、method_array_t 與 method_list_t
method_array_t里面存放的是 method_list_t數(shù)組参歹,所以method_array_t是一個(gè)二維數(shù)組
method_list_t里面存放是的metod_t 是一維數(shù)組
//舉例說明 array_t 和list_t的關(guān)系
class method_array_t :
// C++的語法,是一種泛型隆判,
// method_array_t里面存放的是method_list_t, 二維數(shù)組
//method_list_t 里面存放的是method_t 犬庇,一維數(shù)組
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也是存放的對應(yīng)類型的二維數(shù)組
3侨嘀、method_t
struct method_t {
SEL name; // 方法選擇器臭挽,也就是方法的名字
const char *types; // 方法的返回類型和參數(shù)
MethodListIMP imp; // 方法的存放地址
};
4、總結(jié)
1.objc_class內(nèi)部包含superclass咬腕、cache方法緩存列表欢峰,bits類的信息
2.bits & 一個(gè)掩碼值才能獲取到內(nèi)部的數(shù)據(jù)
3.class_rw_t 是可讀可寫的,目的是方便以后可以向里面插入新的數(shù)據(jù)涨共,如分類纽帖,在程序運(yùn)行的時(shí)候,會將分類和class_ro_t中的數(shù)據(jù)按順序挪放到class_rw_t中举反,最終可以達(dá)到后編譯的類方法可以覆蓋先編譯的類方法
4.class_ro_t 是只讀的 懊直,里面存放的是類的最初的信息
5.method_array_t 是二維數(shù)組里面存放的是method_list_t一維數(shù)組
6.method_list_t存放的是method_t