一趋观、回顧
NSObject -> isa > Class -> objc_class -> objc_object-> isa_t
isa的作用與內(nèi)部結(jié)構(gòu)(上)
isa的作用與內(nèi)部結(jié)構(gòu)(下)
了解了isa的本質(zhì)之后缀皱,再回過頭來看看,NSObject對象對應(yīng)的objc_class結(jié)構(gòu)體內(nèi)部是怎樣的
二、objc_class內(nèi)部結(jié)構(gòu)
NSObject對象的數(shù)據(jù)結(jié)構(gòu)都是存儲在objc_class內(nèi)部的控嗜,即objc_class有什么,NSObject以及 我們繼承后自定義的對象就有什么
// objc_class繼承自objc_object,所以會(huì)有一個(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)系
三、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ù)組
四、method_t
struct method_t {
SEL name; // 方法選擇器迫靖,也就是方法的名字
const char *types; // 方法的返回類型和參數(shù)
MethodListIMP imp; // 方法的存放地址
};
五院峡、總結(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í)候俩垃,會(huì)將分類和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