這篇文章繼 Runtime系列(引文)之后阱当,仍然是一篇引導(dǎo)文,主講類與元類花颗。如果你讀過(guò) Runtime系列(引文),可能會(huì)在其中發(fā)現(xiàn)一個(gè)詞:類對(duì)象
惠拭。那么什么是類對(duì)象
扩劝?
先看一段代碼
NSArray *arr = [NSArray array];
他是怎么運(yùn)行的庸论?
上篇文章中提到,[receiver message]
底層會(huì)調(diào)用id objc_msgSend(id self棒呛, SEL op聂示, ...)
。再來(lái)回顧一下id
是什么
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
typedef struct objc_object *id;
id指向一個(gè)對(duì)象簇秒,可以猜測(cè)[NSArray array]
中的NSArray
也是一個(gè)對(duì)象
鱼喉。可NSArray怎么會(huì)是對(duì)象趋观?這就要引出本文的另一個(gè)主角元類
了扛禽。
元類
其實(shí)NSArray和arr一樣,也是對(duì)象
皱坛,叫做類對(duì)象
编曼。
可以看到,Class
中也有個(gè)isa
指針剩辟,他的指向就是自身的元類掐场。
元類是類對(duì)象的類,類對(duì)象是元類的實(shí)例贩猎。
基于這種設(shè)計(jì)模式熊户,不難發(fā)現(xiàn):
1.我們以前調(diào)用 "+" 開(kāi)頭的類方法實(shí)際是在調(diào)用元類的對(duì)象方法
2.由于每個(gè)類有且只有一個(gè),所以每個(gè)類對(duì)象都是其對(duì)應(yīng)元類的單例
那么,元類是對(duì)象嗎吭服?
答案是肯定的嚷堡,元類是對(duì)象。
如果元類也是對(duì)象噪馏,元類的類又是什么麦到?
元類的類
再來(lái)看一張網(wǎng)上的示意圖
- 圖解
我們接觸到的大部分OC對(duì)象都繼承自NSObject,這里直接以NSObject為例欠肾。
1.每個(gè)實(shí)例對(duì)象的類都是類對(duì)象瓶颠,每個(gè)類對(duì)象的類都是元類對(duì)象,每個(gè)元類對(duì)象的類都是根元類(root meta class的isa指向自身)
2.類對(duì)象的父類最終繼承自根類對(duì)象NSObject刺桃,NSObject的父類為nil
3.元類對(duì)象(包括根元類)的父類最終繼承自根類對(duì)象NSObject
可見(jiàn)粹淋,類與元類是一個(gè)閉環(huán)。