寫在前面
本文主要探究Class
的內(nèi)部結(jié)構(gòu)务漩,博主這里使用的objc4的源碼版本是objc4-838
滨砍,建議大家在看的時候可以下載最新源碼蕴潦。
Class的結(jié)構(gòu)
在前面關(guān)于isa和superclass文章中害碾,我們提到了類對象和元類對象的類型都是Class
瘩例,內(nèi)存里面保存的是:
. isa指針
. superclass指針
. 屬性信息
. 對象方法信息
. 協(xié)議信息
. 成員變量信息
今天我們就來剖析一下Class
的內(nèi)部結(jié)構(gòu)啊胶,驗(yàn)證一下是不是存放的這些信息,廢話不多說了垛贤,我們現(xiàn)在就開始吧焰坪。
Class
是個objc_class
類型的結(jié)構(gòu)體,如下:
typedef struct objc_class *Class;
在objc4
源碼objc-runtime-new.h
文件中聘惦,對objc_class
定義如下:
因?yàn)?code>objc_class結(jié)構(gòu)體中數(shù)據(jù)太多某饰,我這里提煉出來對我們分析結(jié)構(gòu)有用的數(shù)據(jù),如下:
struct objc_class : objc_object {
Class isa; // isa
Class superclass; // superclass
cache_t cache; // 方法緩存
class_data_bits_t bits; // 具體的類信息
}
class_data_bits_t
結(jié)構(gòu)如下:
struct class_data_bits_t {
class_rw_t *data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
}
class_rw_t
結(jié)構(gòu)中善绎,rw
一般表示readwrite(可讀可寫)黔漂,t
一般表示table,結(jié)構(gòu)信息如下:
struct class_rw_t {
uint32_t flags;
uint16_t witness;
Class firstSubclass;
Class nextSiblingClass;
}
// 所有的類會鏈接成一個樹狀結(jié)構(gòu) 利用firstSubclass 和 nextSiblingClass來實(shí)現(xiàn)的搁胆。
class_rw_ext_t
結(jié)構(gòu)信息如下:
struct class_rw_ext_t {
class_ro_t_authed_ptr<const class_ro_t> ro;
method_array_t methods; // 方法列表
property_array_t properties; // 屬性列表
protocol_array_t protocols; // 協(xié)議列表
char *demangledName;
uint32_t version;
};
提醒:
在WWDC2020中晶默,蘋果修改了一些底層的類,其中一個就是我們上面介紹的class_rw_ext_t
畏邢,至于這個類主要作用是什么大家有興趣的可以去詳細(xì)了解一下剂跟,博主這里就不展開來講這個了减途,大概的意思就是:它利用了懶加載的機(jī)制酣藻,在類的methods
、properties
等發(fā)生變化的時候鳍置,才會初始化class_rw_ext_t
來存儲這些列表辽剧,這樣就可以減少90%以前Runtime中的類在rw
中直接復(fù)制ro
中數(shù)據(jù)浪費(fèi)的內(nèi)存。
class_ro_t
結(jié)構(gòu)中税产,ro
一般表示readonly(只讀)怕轿,t
一般表示table,結(jié)構(gòu)信息如下:
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize; // instance對象占用的內(nèi)存空間大小
explicit_atomic<const char *> name; // 類名
// 方法列表(不包括分類的方法列表)
WrappedPtr<method_list_t, method_list_t::Ptrauth> baseMethods;
protocol_list_t * baseProtocols; // 協(xié)議信息列表
const ivar_list_t * ivars; // 成員變量列表
property_list_t *baseProperties; // 屬性信息列表
}
用一張圖來表示Class結(jié)構(gòu):
從上面的結(jié)構(gòu)分析我們可以看到:class對象或meta-class對象里面確實(shí)保存了方法列表砖第、屬性列表撤卢、協(xié)議列表、成員變量列表等信息梧兼。
寫在最后
關(guān)于Class
結(jié)構(gòu)信息我們就分析到這里了放吩,如果有什么不對的地方望指教,歡迎去我的個人技術(shù)博客逛逛羽杰。