天天看點

OC源碼剖析對象的本質

先寫一個 <code>Person</code> 類:

使用 <code>clang</code> 編譯器, <code>clang -rewrite-objc Person.m -o Person.cpp</code>  将 <code>Person.m</code>  編譯成 <code>Person.cpp</code> 檔案,部分代碼如下:

NSObject 類被編譯成了 NSObject_IMPL 的結構體。

Person 類被編譯成了 Person_IMPL 的結構體。

Person 類的内部還增加了一個 NSObject_IMPL 的結構體

我們知道 Person 繼承于 NSObject, 是以它的底層實作中是第一個成員是父類的結構體,就是底層繼承的實作方式。用這樣的方式擁有父類所有的成員變量。

NSObject_IMPL 是 NSObject 類的編譯後的結構體,它的内部隻有一個 Class 類型的 isa 成員變量。我們知道 isa 是 isa_t 類型的,那為什麼在這裡定義成 Class 類型呢?這是為了更加直覺的提現出它代表的是類的資訊,是以在擷取isa 的方法中,将它強制轉換成了Class 類型, 代碼如下:

1.類的底層實作是結構體。

2.繼承是通過把父類的結構體聲明為本類結構體的第一個成員變量實作的。

聯合體: 所有成員可以是不同的類型,但是公用一塊記憶體區域,設定了一個成員變量就會覆寫另一個成員變量的資料。優點是節省空間。

isa 指針占用8位元組,64位。64位中不同的位代表不同的含義:

OC源碼剖析對象的本質
OC源碼剖析對象的本質

對象.isa -&gt; 類.super -&gt; 父類.super -&gt; 根類.super -&gt; nil

類.isa -&gt; 元類.super -&gt; 父元類.super -&gt; 根元類.super -&gt; 根類.super -&gt; nil

元類.isa = 父元類.isa = 根元類.isa = 根元類

下面的列印結果是什麼:

隻有第一個是YES, 剩下的都是NO。 

isKindOfClass: 判斷自己的isa 指向的類是否等于傳入的類,不等于的話,找自己的繼承連中的父類看有沒有等于傳入的類,有則YES,沒有則NO

isMemberOfClass 判斷自己的isa 指向的類是否等于傳入的類,等于則YES,不等于則NO

源碼:

 青山不改,綠水長流,感謝每位佳人支援!