isa指針

在學(xué)習(xí)KVO時(shí)了解到其機(jī)理是通過(guò)runtime改變isa指針的指向來(lái)實(shí)現(xiàn)的,但對(duì)于isa指針還不是太了解,于是查閱相關(guān)資料在這里做一個(gè)整理。

要了解isa指針首先需要了解類、對(duì)象的定義。
Class:
Object-C類型中類的定義是用Class類型來(lái)表示的,實(shí)際上它是一個(gè)指向objc_class類型的結(jié)構(gòu)體指針,定義如下:

// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;


通過(guò)objc.h、runtime.h可以看到類的定義:

// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
//父類,如果該類已經(jīng)是最頂層的根類,那么它為NULL。
Class super_class OBJC2_UNAVAILABLE;
//類名
const char *name OBJC2_UNAVAILABLE;
//類的版本信息,默認(rèn)為0
long version OBJC2_UNAVAILABLE;
//類信息,供運(yùn)行期使用的一些位標(biāo)識(shí)
long info OBJC2_UNAVAILABLE;
//該類的實(shí)例變量大小
long instance_size OBJC2_UNAVAILABLE;
//該類的成員變量鏈表
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
//方法定義的鏈表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
//方法緩存
struct objc_cache *cache OBJC2_UNAVAILABLE;
//協(xié)議鏈表
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

其中:

  • isa:在OC中需要明確對(duì)象和類并沒(méi)有本質(zhì)的區(qū)別,類也是對(duì)象,類中有一個(gè)指向元類metaClass的isa指針,關(guān)于元類會(huì)在后邊進(jìn)行介紹。

  • cashe:當(dāng)一個(gè)對(duì)象接收到某個(gè)消息時(shí),它會(huì)根據(jù)isa指針去查找能夠響應(yīng)消息的對(duì)象,每次調(diào)用這個(gè)方法后就會(huì)緩存到cache中而不必每次都到methodLists遍歷。

objc_object與id:
objc_object表示一個(gè)對(duì)象,實(shí)際上它表示一個(gè)類實(shí)例的結(jié)構(gòu)體,定義如下:

struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};

typedef struct objc_object *id;

可以看到,對(duì)象中包含一個(gè)指向其類的isa指針。當(dāng)我們向一個(gè)對(duì)象發(fā)送消息時(shí),Runtime會(huì)根據(jù)實(shí)例對(duì)象的isa指針找到這個(gè)實(shí)例對(duì)象所屬的類,Runtime庫(kù)會(huì)在類的方法列表及父類的方法列表中去尋找與消息對(duì)應(yīng)的selector指向的方法。找到后即運(yùn)行這個(gè)方法。

元類(Meta Class):
前面已經(jīng)提到類也是對(duì)象,當(dāng)向?qū)ο蟀l(fā)送消息的時(shí)會(huì)根據(jù)對(duì)象isa指針查找所屬類的對(duì)應(yīng)方法,對(duì)于類方法而言呢,它應(yīng)該去哪查找方法?如:

NSString *string = [NSString string];

根據(jù)前面提到的機(jī)制,此時(shí)要查找相應(yīng)類對(duì)象的+string方法則isa指針需要查找包含這個(gè)方法的類,即元類metaClass:類對(duì)象所屬的類。當(dāng)我們向一個(gè)對(duì)象發(fā)送消息時(shí),runtime會(huì)在這個(gè)對(duì)象所屬的這個(gè)類的方法列表中查找方法;而向一個(gè)類發(fā)送消息時(shí),會(huì)在這個(gè)類的元類的方法列表中查找。

元類也是一個(gè)類,也可以向它發(fā)送一個(gè)消息,那么它的isa又是指向什么呢?為了不讓這種結(jié)構(gòu)無(wú)限延伸下去,Objective-C的設(shè)計(jì)者讓所有的元類的isa指向基類的元類,以此作為它們的所屬類。即,任何NSObject繼承體系下的元類都使用NSObject的元類作為自己的所屬類,而基類的元類的isa指針是指向它自己。這樣就形成了一個(gè)完美的閉環(huán)。

通過(guò)上面的描述,我們就可以描繪出類的一個(gè)繼承體系了,如下圖所示:


類的繼承體系圖

PS: I am xinghun who is on the road.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容