標籤:
首先,你要先弄清楚什麼是類,什麼是對象。(為了說清楚這個問題,先舉個栗子:類—>對象—>執行個體:人類是類;某個人是對象;你是執行個體;執行個體本身也是對象。這下基本能理解其中的差別了,要是還是搞不清楚,自己去google一下吧。)
對象
在Objective-C中,每一個對象都是某個類的執行個體,且這個對象的isa指標指向它所屬的類。開啟 objc-private.h檔案,在第126行可以看到 Objective-C???? 對象的定義struct objc_object ,Objective-C中對象本質上是結構體對象,其中isa是它的唯一私人變數。
同樣的,在第48行到第52行,可以找到 Class 和 id 類型定義,這也是為什麼 id類型可以指向任意對象的原因。其中objc_class 就是 Objective-C 中類的定義。
類
對象的類不僅描述了對象的資料:對象佔用記憶體大小,成員變數的類型布局等,還描述了對象的行為:對象能響應的資訊,實現的實力方法(很多對runtime的講解的文章,其實就是在這一塊做文章)等。因此,當我們調用[receiver message]給一個對象發送訊息的時候,這個對象能否響應這個訊息就需要通過isa找到它所屬的類(包括superClass)才能知道。
開啟 objc-runtime-new.h ,在687行可以找到 Objective-C 中 struct objc_class 的定義。可以看到Objective-C中類也是一個結構體對象,並且繼承了 struct objc_object 。
所以: Objective-C 中的類本質上也是對象,我們稱之為類對象。按照之前說的,所有的對象都是某個類的執行個體,那麼類對象又是什麼什麼類的執行個體,這是個值得思考的問題。
我們知道 Objective-C 中有一個非常特殊的NSObject,絕大部分的類都繼承自它,它是 Objective-C 中兩個rootClass鐘的一個,另一個是NSProxy(另一篇文章有)。開啟 NSObject.h ,可以看到NSObject 類就只有一個成員變數 isa, 所有繼承自NSObject得類也都會有這個成員變數。
元類
本質上講, Objective-C 中的類也是對象,它也是某個類的執行個體,這個類我們稱之為元類(metaclass)。
因此,我們可以調用類方法,比如[NSObject new]來給類對象發送訊息。同樣的,類對象能否響應這個訊息,要通過isa找到類對象所屬的類(元類)才能知道。也就是說,執行個體方法儲存在類中,而類方法儲存在元類中。
元類也是對象(元類對象),元類也是某個類的執行個體,這個類我們稱之為根元類(root metaclass)。特殊的是:所有的元類所屬的類都是同一個根元類(當然根元類也是元類,所以它所屬的類也是根元類,即它本身)。根元類所指的就是根類的元類,具體說就是根類NSObject 對應的元類。
上經典圖:通過上面的解析,再來看這張圖,清晰多了。
Objective-C 源碼(一):物件模型