objc_class
首先了解兩個(gè)重要類型,id和class
id 與 Class,在 <objc/objc.h> 中可以找到兩者定義
// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
// A pointer to an instance of a class.
typedef struct objc_object *id;
id 與 Class 都是指向結(jié)構(gòu)體的指針。
id與Class的結(jié)構(gòu)體區(qū)別:
//-----id 的結(jié)構(gòu)體 ------
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
//-----Class的結(jié)構(gòu)體
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
//指向該類的父類
Class super_class OBJC2_UNAVAILABLE;
//一個(gè) C 字符串,指示類的名稱。我們可以在運(yùn)行期,通過這個(gè)名稱查找到該類(通過:id objc_getClass(const char *aClassName))或該類的 metaclass(id objc_getMetaClass(const char *aClassName))
const char *name OBJC2_UNAVAILABLE;
//類的版本信息,默認(rèn)初始化為 0。我們可以在運(yùn)行期對(duì)其進(jìn)行修改(class_setVersion)或獲?。╟lass_getVersion)。
long version OBJC2_UNAVAILABLE;
//供運(yùn)行期使用的一些位標(biāo)識(shí)。
long info OBJC2_UNAVAILABLE;
//該類的實(shí)例變量大小
long instance_size OBJC2_UNAVAILABLE;
//指向 objc_ivar_list 的指針,存儲(chǔ)每個(gè)實(shí)例變量的內(nèi)存地址
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
//與 info 的一些標(biāo)志位有關(guān),如果 info 設(shè)置了 CLS_CLASS 則 objc_method_list 存儲(chǔ)實(shí)例方法,如果設(shè)置的是 CLS_META 則存儲(chǔ)類方法
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
//指向 objc_cache 的指針,用來(lái)緩存最近使用的方法,以提高效率
struct objc_cache *cache OBJC2_UNAVAILABLE;
//objc_protocol_list 的指針,存儲(chǔ)該類聲明要遵守的正式協(xié)議。
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
isa:是一個(gè) objc_class 類型的指針。
objc_object可以這樣寫:
typedef struct objc_object {
objc_class isa;
} *id;
Class 是一個(gè) objc_class 結(jié)構(gòu)類型的指針;而 id(任意對(duì)象) 是一個(gè) objc_object 結(jié)構(gòu)類型的指針,其第一個(gè)成員是一個(gè) objc_class 結(jié)構(gòu)類型的(isa)指針。
objc_object對(duì)象創(chuàng)建時(shí),運(yùn)行時(shí)系統(tǒng)會(huì)在類的方法列表及父類的方法列表中去尋找與消息對(duì)應(yīng)的selector指向的方法,找到后即運(yùn)行這個(gè)方法。
類對(duì)象所屬的類型(也就是isa指針?biāo)赶虻念愋停┦橇硗庖粋€(gè)類型,叫做元類(metaclass),用來(lái)表述類對(duì)象本身所具備的元數(shù)據(jù),“類方法”就定義在此處。

objc_selector
typedef struct objc_selector *SEL;
//這一點(diǎn)是猜測(cè)的在runtime的源碼內(nèi)沒有找到具體的objc_selector定
struct objc_selector{
void *sel_id;
const char *sel_types;
};
NSLog(@"SEL=%s",@selector(print))
會(huì)輸出為 SEL=print,SEL返回方法名。
所以我覺得 SEL 理解為一個(gè) char* 指針。SEL用來(lái)存儲(chǔ)方法的編號(hào),方便系統(tǒng)查詢方法。
IMP指針
IMP指針?biāo)侵赶蛞粋€(gè)方法實(shí)現(xiàn)的指針,每一個(gè)方法都有一個(gè)對(duì)應(yīng)的IMP
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif
IMP 的含義:IMP 是一個(gè)函數(shù)指針,這個(gè)被指向的函數(shù)包含一個(gè)接收消息的對(duì)象id(self 指針), 調(diào)用方法的選標(biāo) SEL (方法名),以及不定個(gè)數(shù)的方法參數(shù),并返回一個(gè)id。也就是說 IMP 是消息最終調(diào)用的執(zhí)行代碼,是方法真正的實(shí)現(xiàn)代碼 。
objc_method
typedef struct objc_method *Method;
typedef struct objc_ method {
SEL method_name;
char *method_types;
IMP method_imp;
};
一個(gè)方法 Method,其包含一個(gè)方法選標(biāo) SEL – 表示該方法的名稱,一個(gè)types – 表示該方法參數(shù)的類型,一個(gè) IMP - 指向該方法的具體實(shí)現(xiàn)的函數(shù)指針