首先我們之前知道isa的指針的指向結論是:
1.instance對象的isa指向class對象
2.clsaa對象的isa指向meta-class
3.meta-class對象的isa指向基類的meta-class對象
這篇博客,我們將探究isa指針指向哪里?并且會從代碼層的內存地址證明isa指針的指向。
首先instance對象的isa指針指向class對象,我們就可以創建一個instance對象
從上面的截圖運行結果可以看出stu的isa的0x001d8001000084e9?和GDStudent的isa的0x00000001000084e8并不一樣,跟我們之前說的結果不一致?
其實啊,在arm64之前,也就是iPhone 5s之前其實是一致的,而在arm64以后它需要一個&位運算操作,需要stu的isa與ISA_MASK這個常量位運算一次,也就是
0x001d8001000084e9 &?ISA_MASK ,現在我們蘋果源碼看一下ISA_MASK是什么東西,請看下面的截圖
需要這份源碼的,請移步下載:蘋果源碼下載地址
因為我們創建的是mac程序,所以我們復制下面的ISA_MASK位運算操作一次,請看下面的結果:
從紅色的結果是不是一摸一樣,正好驗證了instance對象的isa指針指向class對象!
此時是不是666!??
2.clsaa對象的isa指向meta-class
細心的同學可能可能發現我們無法輸出classStu的isa,就像上面的綠色不是structure,我們點一下class的jump to Definition查看它的源碼定義
這樣我們看最后那種紅色部分,確實是有個isa,此時怎么處理呢?我們可以定義一個一摸一樣的結構體來替換一下class就行了如下代碼:
struct ?gd_objc_class {
? ? Class ?isa;
? ? Class ?superclass;
};
objc_class前面加gd是防止重名,編譯不通過,所以隨便寫啥都行
現在就可以驗證了
這樣結果就是一摸一樣可以驗證了!
這樣也是從代碼層驗證了
1.instance對象的isa指向class對象
2.clsaa對象的isa指向meta-class
3.meta-class對象的isa指向基類的meta-class對象
接下來我將用代碼證明
1.對象方法、屬性、成員變量、協議信息存放在class對象中
2.類方法存放在meta-class對象中
3.成員變量的具體值是存放在instance對象中