對于oc對象模型,我們清楚在運(yùn)行時(shí)一個(gè)類的對象可以通過它自身的isa指針找到它所歸屬的類节槐,比如一個(gè)NSString類的實(shí)例對象aaa,調(diào)用它的一個(gè)實(shí)例方法 [aaa substringFromIndex:1]谦炬, 實(shí)際就是向?qū)ο骯aa發(fā)送了一個(gè)消息比吭,運(yùn)行時(shí)庫會(huì)根據(jù)aaa的isa指針找到這個(gè)對象所歸屬的類,這個(gè)類包含一個(gè)所有實(shí)例方法的以及一個(gè)指向superclass的指針以便可以找到父類的實(shí)例方法严肪, 運(yùn)行時(shí)庫會(huì)在類的方法列表以及父類(們)的方法列表中尋找符合這個(gè)selector( 這里這個(gè)selector是”substringFromIndex:1")的方法史煎。找到后即運(yùn)行這個(gè)方法。關(guān)鍵點(diǎn)就是類要定義這個(gè)你發(fā)送給對象的消息)驳糯。
那么什么是 meta-class
一個(gè)oc類其實(shí)也是一個(gè)對象篇梭,意思就是你向一個(gè)類發(fā)送消息,也就是調(diào)用一個(gè)類方法比如 [NSString alloc]酝枢, 因?yàn)槊恳粋€(gè)OC的類本身也是一個(gè)對象恬偷。也就是說Class的數(shù)據(jù)結(jié)構(gòu)必然也是以isa指針開始的, 在二進(jìn)制級別上與objc_object是完全兼容的帘睦。然后一個(gè)類結(jié)構(gòu)的下一個(gè)字段一定是一個(gè)指向super class的指針(或者指向nil袍患,對于基類而言)。
一個(gè)類如何定義有很多方法竣付,依賴于你的運(yùn)行時(shí)庫版本诡延,但是不管哪種方法,他們都是以一個(gè)isa作為第一個(gè)字段卑笨,接著是superclass字段孕暇。
為了可以調(diào)用類方法,這個(gè)類的isa指針必須指向一個(gè)包含這些類方法的類結(jié)構(gòu)體赤兴。
這樣就引出了meta-class的概念:meta-class是一個(gè)類對象的類妖滔。
簡單解釋下:
當(dāng)你向一個(gè)對象發(fā)送消息時(shí),runtime會(huì)在這個(gè)對象所屬的那個(gè)類的方法列表中查找桶良。
當(dāng)你向一個(gè)類發(fā)送消息時(shí)座舍,runtime會(huì)在這個(gè)類的meta-class的方法列表中查找。
meta-class之所以重要陨帆,是因?yàn)樗鎯?chǔ)著一個(gè)類的所有類方法曲秉。每個(gè)類都會(huì)有一個(gè)單獨(dú)的meta-class采蚀,因?yàn)槊總€(gè)類的類方法基本不可能完全相同。
meta-class的類又是什么呢承二?
meta-class榆鼠,就像Class一樣,也是一個(gè)對象亥鸠。你依舊可以向它發(fā)送消息調(diào)用函數(shù)妆够,自然的,meta-class也會(huì)有一個(gè)isa指針指向其所屬類负蚊。所有的meta-class使用基類的meta-class作為他們的所屬類神妹。具體而言,任何NSObject繼承體系下的meta-class都使用NSObject的meta-class作為自己所屬的類家妆。
根據(jù)這個(gè)規(guī)則鸵荠,所有的meta-class使用基類的meta-class作為它們的類,而基類的meta-class也是屬于它自己伤极,也就是說基類的meta-class的isa指針指向它自己蛹找。(譯:完美的閉環(huán))
類和meta-class的繼承
就像一個(gè)類使用super_class指針指向自己的父類一樣,meta-class的super_class會(huì)指向類的super_class的meta-class塑荒。一直追溯到基類的meta-class熄赡,它的super_class會(huì)指向基類自身。
isa 和繼承的關(guān)系結(jié)論:
meta-class是類對象的類齿税,每個(gè)類都有自己單獨(dú)的meta-class。所有的類對象并不會(huì)屬于同一個(gè)meta-class炊豪。
meta-class要保證類對象具有繼承體系中基類的所有實(shí)例和類方法凌箕,以及繼承體系中的所有中間類方法。對于所有NSObject繼承體系下的類词渤,NSObject的實(shí)例方法和協(xié)議方法對他們和他們meta-class的對象都要有效牵舱。
所有的meta-class使用基類(NSObject)的meta-class作為自己的基類,對于頂層基類的meta-class也是一樣缺虐,只是它指向自己而已芜壁。