objc_class的內(nèi)部結(jié)構(gòu)

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,所以會有一個屬性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)建類的時候的初始信息

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中多了一個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是一個二維數(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 & 一個掩碼值才能獲取到內(nèi)部的數(shù)據(jù)
3.class_rw_t 是可讀可寫的,目的是方便以后可以向里面插入新的數(shù)據(jù),如分類,在程序運行的時候,會將分類和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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容