我們平時(shí)編寫的Objective-C代碼,底層實(shí)現(xiàn)其實(shí)都是C\C++代碼
所以O(shè)bjective-C的面向?qū)ο蠖际腔贑\C++的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的;那么 Objective-C的對(duì)象、類主要是基于C\C++的什么數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的?
答案是結(jié)構(gòu)體,因?yàn)橹挥薪Y(jié)構(gòu)體能存儲(chǔ)不同類型的對(duì)象。下面我們一步一步驗(yàn)證一下摔笤,NSObject 對(duì)象的本質(zhì)是不是就是結(jié)構(gòu)體,需要先將oc代碼轉(zhuǎn)成c/c++代碼
轉(zhuǎn)換之前我們需要指定一個(gè)具體系統(tǒng)以及架構(gòu)垦写,就以iphone的64位架構(gòu)來區(qū)分吕世,補(bǔ)充一點(diǎn)是模擬器的架構(gòu)是i386、32bit是arm7梯投、64bit是arm64命辖,所以我們需要執(zhí)行的代碼是
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
然后生成一個(gè)main-arm64.cpp對(duì)應(yīng)的c/c++代碼,在?main-arm64.cpp 內(nèi)我們可以找到NSObject_IMPL這個(gè)結(jié)構(gòu)體分蓖,它就是NSObject的具體實(shí)現(xiàn)尔艇;因?yàn)榻Y(jié)構(gòu)體內(nèi)只有一個(gè)isa成員,所以isa的地址就是當(dāng)前結(jié)構(gòu)體在內(nèi)存中的地址么鹤,所以obj指針中存儲(chǔ)的地址就是isa的地址值终娃。
接下來,延伸一到面試題
問:一個(gè)NSObject 對(duì)象占用多少內(nèi)存蒸甜?
我們可以看到?malloc_size 返回的的確是16個(gè)字節(jié)棠耕,那么為什么class_getInstanceSize 返回的是8呢?通過查看源碼注釋我們知道柠新,其實(shí)class_getInstanceSize返回的是對(duì)象成員變量所占用的大小昧辽,但是系統(tǒng)分配的內(nèi)存的時(shí)候,如果你的內(nèi)存大小小于16登颓,那么會(huì)按照16個(gè)字節(jié)來分配。
答:系統(tǒng)分配了16個(gè)字節(jié)給NSObject對(duì)象红氯,但是NSObject對(duì)象內(nèi)部只使用了8個(gè)字節(jié)的空間(64bit環(huán)境下)