這篇文章繼 Runtime系列(引文)之后,仍然是一篇引導文,主講類與元類。如果你讀過 Runtime系列(引文),可能會在其中發現一個詞:類對象
。那么什么是類對象
?
先看一段代碼
NSArray *arr = [NSArray array];
他是怎么運行的?
上篇文章中提到,[receiver message]
底層會調用id objc_msgSend(id self, SEL op, ...)
。再來回顧一下id
是什么
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
typedef struct objc_object *id;
id指向一個對象,可以猜測[NSArray array]
中的NSArray
也是一個對象
。可NSArray怎么會是對象?這就要引出本文的另一個主角元類
了。
元類
其實NSArray和arr一樣,也是對象
,叫做類對象
。
Class.png
可以看到,Class
中也有個isa
指針,他的指向就是自身的元類。
元類是類對象的類,類對象是元類的實例。
基于這種設計模式,不難發現:
1.我們以前調用 "+" 開頭的類方法實際是在調用元類的對象方法
2.由于每個類有且只有一個,所以每個類對象都是其對應元類的單例
那么,元類是對象嗎?
答案是肯定的,元類是對象。
如果元類也是對象,元類的類又是什么?
元類的類
再來看一張網上的示意圖
示意圖.png
- 圖解
我們接觸到的大部分OC對象都繼承自NSObject,這里直接以NSObject為例。
1.每個實例對象的類都是類對象,每個類對象的類都是元類對象,每個元類對象的類都是根元類(root meta class的isa指向自身)
2.類對象的父類最終繼承自根類對象NSObject,NSObject的父類為nil
3.元類對象(包括根元類)的父類最終繼承自根類對象NSObject
可見,類與元類是一個閉環。