馬上又要開始新的一天了:加油凳兵!
- 在平常的iOS工程中我們?nèi)フ叶xClass的地方會發(fā)現(xiàn)如下代碼
typedef struct objc_class *Class;
再去看 objc_class 的實現(xiàn)
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
注意到:OBJC2_UNAVAILABLE 捏境。意味著在objc2.0中這個結(jié)構(gòu)體已經(jīng)被廢棄了斤寂。因此我們只能去看objc4源碼里有沒有
- 于是我們?nèi)bjc4開源源碼里搜索找到了最新的Class的實現(xiàn)
struct objc_object {
private:
isa_t isa;
... //方法函數(shù)
}
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
class_rw_t *data() {
return bits.data();
}
... //方法函數(shù)
}
這兩個結(jié)構(gòu)體列出了其所有的成員變量以及獲取class_rw_t的方法
C++的結(jié)構(gòu)體類似于OC的類协怒,有繼承關(guān)系纽竣。
因此objc_class的結(jié)構(gòu)可以寫為
struct objc_class {
Class isa;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
class_rw_t *data() {
return bits.data();
}
... //方法函數(shù)
}
- 通過 bits & FAST_DATA_MASK 可以獲得一個class_rw_t的結(jié)構(gòu)體
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint32_t version;
const class_ro_t *ro; //存放類的初始信息
method_array_t methods; //方法列表
property_array_t properties; //屬性列表
protocol_array_t protocols; //協(xié)議列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
#if SUPPORT_INDEXED_ISA
uint32_t index;
#endif
... //方法函數(shù)
}
- 通過 class_rw_t里的ro指針可以找到class_ro_t對應(yīng)的結(jié)構(gòu)體存儲:
//這里存放的是類編譯時候的初始信息
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;
};
參考一下小碼哥的導(dǎo)圖