前置文章: iOS底層之類的重要組成部分-isa結構體分析
前言
從上篇文章中我們得知對象的isa
指針中的shiftcls
存儲的是類指針的值,那么這個值到底代表什么呢,接下來讓我們探索一下。
一、isa指針探索
首先我們先用對象的isa指針 & ISA_MASK
得到如下結果:
isa指針的shiftcls的值
WJPerson
,那么這個WJPerson
會不會是類的地址的,接下來我們打印下WJPerson
的類地址再來驗證一下WJPerson類的地址
isa
的指針的shiftcls
的結果一模一樣,而shiftcls
存儲的又是類指針的值,所以我們可以得出結論:對象的isa指針指向的是類對象
。那么類對象的isa指針指向什么呢?我們再來實驗一下
類對象的isa指針結果
WJPerson
,但是這個WJPerson
和第一次打印的WJPerson
的指針不一樣,怎么回事,難道OC
會創建兩個一模一樣的類嗎?我們來測試下
void testClassPoint(){
Class class1 = [WJPerson class];
Class class2 = [WJPerson alloc].class;
Class class3 = object_getClass([WJPerson alloc]);
Class class4 = [WJPerson alloc].class;
NSLog(@"\n%p \n%p \n%p \n%p", class1, class2, class3, class4);
}
打印結果
0x100002140
0x100002140
0x100002140
0x100002140
從上述結果可知,OC
只會存在一個類。那么我們之前獲取到的第二個WJPerson
是什么呢?
有的同學可能會知道在OC
中還有一個元類
的概念,元類
和類
有些相似,我們知道類
是使用存儲對象
信息的,那么元類
就是存儲類對象
信息的類。說了這么多,空口無憑,我們再來驗證下
驗證元類地址
類對象的isa指針指向元類
。接下來我們再看下
元類
的isa
指針指向什么。元類的isa指向
NSObject
,那么這個NSObject
是到底是類
還是元類
,接下來我們打印下NSObject
的類
和元類
的地址NSObject類和元類的地址
alloc
重新創建一個對象獲得的地址也一樣。從圖中我們發現WJPerson
的元類的isa指針指向的是NSObject
的元類。我們一般把NSObject
叫做根類
,那么NSObject
的元類就叫做根元類
。所以我們可以得出結論:元類的isa指針指向的是根元類
。我們在看下根元類的isa指向的是什么。
根元類的isa指向
根元類的isa指針指向的是本身
,這樣就形成了一個閉環。我們總結一下我們的驗證結果
- 對象的isa指針指向的是類對象
- 類對象的isa指針指向元類
- 元類的isa指針指向的是根元類
- 根元類的isa指針指向的是本身
isa走位圖