在iOS
開發(fā)工程中陵刹,我們每天都會使用到ObjC
杂靶,也會用到runtime
的很多操作msgSend
持搜,method_swizzling
吉殃,objc_setAssociatedObject
辞居,objc_getAssociatedObject
等常用的runtime
操作,那runtime
究竟是怎樣實(shí)現(xiàn)的呢蛋勺?我們底層的數(shù)據(jù)結(jié)構(gòu)又是怎樣的呢瓦灶?帶著這些問題,開始學(xué)習(xí)runtime
相關(guān)的內(nèi)容抱完。
源碼地址: objc4源代碼
我們看到我們最常引入的頭文件#import<objc/runtime.h>
贼陶,我們可以看到runtime
定義了ObjC
的運(yùn)行時狀態(tài),類巧娱、屬性碉怔、方法、協(xié)議禁添、拓展等內(nèi)容的實(shí)現(xiàn)撮胧。下面我們從類的定義開始閱讀。
objc_class
類的定義老翘,定義具體代碼如下
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;
從上面的代碼可以看出來類的定義是以結(jié)構(gòu)的形式實(shí)現(xiàn)芹啥,包含有類本身及父類的信息,屬性列表铺峭、方法列表墓怀、緩存和協(xié)議列表。
objc_ivar
objc_ivar_list
定義了屬性類的屬性列表卫键,在objc_ivar_list
包含了一個objc_ivar
的一個數(shù)組捺疼,通過這兩個結(jié)構(gòu)實(shí)現(xiàn)類的屬性存儲。
struct objc_ivar {
char * _Nullable ivar_name OBJC2_UNAVAILABLE;
char * _Nullable ivar_type OBJC2_UNAVAILABLE;
int ivar_offset OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
struct objc_ivar_list {
int ivar_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
objc_method
和屬性一樣objc_method_list
中同樣包含了一個objc_method
的數(shù)組永罚,通過這兩個方法實(shí)現(xiàn)了方法列表啤呼。
struct objc_method {
SEL _Nonnull method_name OBJC2_UNAVAILABLE;
char * _Nullable method_types OBJC2_UNAVAILABLE;
IMP _Nonnull method_imp OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
struct objc_method_list {
struct objc_method_list * _Nullable obsolete OBJC2_UNAVAILABLE;
int method_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_method method_list[1] OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
Protocol
protocol
的實(shí)現(xiàn)方式和method
和ivar
類似,他們都有一個objc_protocol_list
以及Protocol
的數(shù)組去實(shí)現(xiàn)協(xié)議的列表呢袱,不同的是Protocol
的實(shí)現(xiàn)不再是一個結(jié)構(gòu)官扣,而是一個繼承自NSObject
的類。
struct objc_protocol_list {
struct objc_protocol_list * _Nullable next;
long count;
__unsafe_unretained Protocol * _Nullable list[1];
};
objc_category
category
定義了Category
的數(shù)據(jù)結(jié)構(gòu)羞福,通過category_name
區(qū)分不同的category
惕蹄,通過class_name
關(guān)聯(lián)相關(guān)的類。
struct objc_category {
char * _Nonnull category_name OBJC2_UNAVAILABLE;
char * _Nonnull class_name OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable instance_methods OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable class_methods OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
如上就是runtime
相關(guān)的定義治专。然后一些常用的操作又是怎么實(shí)現(xiàn)的呢卖陵?我們在進(jìn)一步的學(xué)習(xí)其他的相關(guān)操作。
更好的閱讀體驗(yàn)可以參考個人網(wǎng)站:https://zevwings.com