iOS底層探究-isa結構分析

前言

相信大部分多年工作經驗的iOS開發(fā)者知道了OC的對象本質上是一個基于C語言封裝的結構體。這個結構體有一個成員叫isa,它指向這個對象的類對象,那么今天我就來深入探究下這個isa成員。

驗證對象是否真的是結構體,結構體是否有isa成員。

1.我們創(chuàng)建一個工程,在man.m文件內定義一個繼承NSObject的對象LGPerson,里面放一個NSString屬性name。如下圖

main.m

2.用Clang編譯器將剛剛編寫的main.m文件編譯成C++文件。

用終端cd到剛剛創(chuàng)建的工程根目錄下,然后執(zhí)行clang -rewrite-objc main.m -o main.cpp把目標文件編譯成c++文件

編譯成C++

然后我們打開main.cpp文件,搜索LGPerson結果如下,我們發(fā)現了LGPerson真的是個結構體,下圖紅框標注iOS底層聲明了一個objc_object結構體LGPerson,我們記住這個objc_object結構體名稱。
LGPerson

3.我們在main.m文件導入頭文件#import <objc/objc.h>,按住command鼠標左鍵點擊頭文件跳轉進去objc源碼,然后我們搜索objc_object,發(fā)現如下圖所示iOS底層對象真的是結構體封裝,并且真的里面有一個isa。

objc文件源碼

isa里面有哪些信息,是不是真的有類對象,還有沒有其他信息,我們接下來看看

1.我們繼續(xù)打開之前博客提到的objc源碼工程,我們看到紅框里面isa是一個union聯(lián)合體。

結構體(struct)中所有變量是“共存”的——優(yōu)點是“有容乃大”, 全面;缺點是struct內存空間的分配是粗放的,不管用不用,全分配。
聯(lián)合體(union)中是各變量是“互斥”的——缺點就是不夠“包容”; 但優(yōu)點是內存使用更為精細靈活,也節(jié)省了內存空間。

isa結構

大家可以具體了解下聯(lián)合體概念,接下來我們點擊聯(lián)合體isa里面的ISA_BITFIELD看到這是一個宏定義
isa

那么上面宏定義里面這些nonpointer :1是代表什么呢?
nonpointer:表示是否對 isa 指針開啟指針優(yōu)化 0:純isa指針,1:不止是類對象地址,isa 中包含了類信息、對象的引用計數等。
has_assoc:關聯(lián)對象標志位,0沒有,1存在。
has_cxx_dtor:該對象是否有 C++ 或者 Objc 的析構器,如果有析構函數,則需要做析構邏輯, 如果沒有,則可以更快的釋放對象。
shiftcls:存儲類指針的值。開啟指針優(yōu)化的情況下,在 arm64 架構中有 33 位用來存儲類指針,上面圖中74行# elif __x86_64__表示在x86_64(模擬器,Mac端)內核下占44位。
magic:用于調試器判斷當前對象是真的對象還是沒有初始化的空間。
weakly_referenced:志對象是否被指向或者曾經指向一個 ARC 的弱變量,
沒有弱引用的對象可以更快釋放。
deallocating:標志對象是否正在釋放內存。
has_sidetable_rc:當對象引用技術大于 10 時,則需要借用該變量存儲進位。
extra_rc:當表示該對象的引用計數值,實際上是引用計數值減 1, 例如,如果對象的引用計數為 10,那么 extra_rc9。如果引用計數大于 10, 則需要使用到下面的 has_sidetable_rc。
isa占8字節(jié)64位,第一個nonpointer :1,表示從右開始長度為1的字節(jié)位數信息為nonpointer
同理第四排 shiftcls :44表示從第4位開始往左長度為44位存儲類指針
好了,看完資料我們了解了isa里面第4位到47位存儲了類指針,接下來就是驗證環(huán)節(jié)了,注意我們是在模擬器運行,如果是真機運行那么shiftcls就只占33位了。
image.png

我們打個斷點然后在控制臺按照紅框的指令打印LGPerson對象p的數據,最后拿到p的首內存地址數據0x001d800100002205(也就是isa字段),然后我們通過輸入p/t LGPerson.class打印LGPerson類所存儲的2進制地址。
isa內4-47位數據和LGPerson類存儲指針2進制地址

我們發(fā)現一個驚人的事實,那就是我紅框內的數據一模一樣!從右起第4位開始到第47位中間44位數據一模一樣!這個完全驗證了我們上面貼圖的isa內的shiftcls : 44;的定義。

結論

對象其實是底層封裝好的結構體,結構體內第一個成員為isa(這個對象所繼承的類指針),其中該類指針放在isa的第4-47位(x86_64 模擬器)或第4-37位(arm64 真機)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容