class_ro_t 和 class_rw_t 的區(qū)別?
struct class_rw_t {
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_array_t methods;
property_array_t properties;
protocol_array_t protocols;
Class firstSubclass;
Class nextSiblingClass;
};
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
uint32_t reserved;
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_rw_t結(jié)構(gòu)體內(nèi)有一個指向class_ro_t結(jié)構(gòu)體的指針。
每個類都對應(yīng)有一個class_ro_t結(jié)構(gòu)體和一個class_rw_t結(jié)構(gòu)體。在編譯期間,class_ro_t結(jié)構(gòu)體就已經(jīng)確定,objc_class中的bits的data部分存放著該結(jié)構(gòu)體的地址。在runtime運行之后,具體說來是在運行runtime的realizeClass 方法時,會生成class_rw_t結(jié)構(gòu)體,該結(jié)構(gòu)體包含了class_ro_t,并且更新data部分,換成class_rw_t結(jié)構(gòu)體的地址。
用兩張圖來說明這個過程:
類的realizeClass運行之前:
image.png
類的realizeClass運行之后:
image.png
細(xì)看兩個結(jié)構(gòu)體的成員變量會發(fā)現(xiàn)很多相同的地方,他們都存放著當(dāng)前類的屬性、實例變量、方法、協(xié)議等等。區(qū)別在于:class_ro_t存放的是編譯期間就確定的;而class_rw_t是在runtime時才確定,它會先將class_ro_t的內(nèi)容拷貝過去,然后再將當(dāng)前類的分類的這些屬性、方法等拷貝到其中。所以可以說class_rw_t是class_ro_t的超集,當(dāng)然實際訪問類的方法、屬性等也都是訪問的class_rw_t中的內(nèi)容