
先在main.m定義了一個繼承于NSObject的類 然后通過命令行 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m 獲得生成的C\C++代碼 打開生成后的main.cpp可以看到




IMPL的意思就是implementation實現(xiàn)的意思上圖可以看的比較清楚在OC的頭文件里面NSObject底層實現(xiàn)就是左邊里面只有一個成員變量isa,在底層實現(xiàn)里面NSObject本質(zhì)他就是一個結(jié)構(gòu)體(圖的右邊)。Class點進(jìn)去看就是一個指向結(jié)構(gòu)體的指針,在64位環(huán)境下占8個字節(jié),所以NSObject在內(nèi)存中就占8個字節(jié),但是真正的的情況是占16個字節(jié),通過運(yùn)行時runtime可以發(fā)現(xiàn),且看下面分析。





是通過一個instanceSize的方法返回最后的大小,而instanceSize方法里面寫的最低返回就是16個字節(jié),硬性規(guī)定了最少16個字節(jié)。如果是NSObject的話通過size_t size = alignedInstanceSize() + extraBytes;拿出來的是8個字節(jié)。方法alignedInstanceSize返回的是成員變量大小,extraBytes額外的一般來說是0字節(jié)。



剛才我們通過源碼了解到系統(tǒng)為obj分配了16個字節(jié),上圖綠色框框中框出了16個字節(jié),1個16進(jìn)制位代表4個2進(jìn)制位,2個16進(jìn)制位就代表8個2進(jìn)制位,也就是1個字節(jié)。前8個字節(jié)就代表isa,后面8個字節(jié)都是00,再后面就不是0,所以能推斷出這16個字節(jié)是連續(xù)的,紅色框框框的就是其它的內(nèi)存,最嚴(yán)謹(jǐn)?shù)姆椒ㄟ€是通過運(yùn)行時獲取。
最后總結(jié)一下就是:
1.一個NSObject對象占用多少內(nèi)存?
系統(tǒng)分配了16個字節(jié)給NSObject對象(通過malloc_size函數(shù)獲得)
但NSObject對象內(nèi)部只使用了8個字節(jié)的空間(64bit環(huán)境下,可以通過class_getInstanceSize函數(shù)獲得)
創(chuàng)建一個實例對象,至少需要多少內(nèi)存?
#import <objc/runtime.h>
class_getInstanceSize([NSObject class]);
創(chuàng)建一個實例對象,實際上分配了多少內(nèi)存?
#import <malloc/malloc.h>
malloc_size((__bridge const void *)obj);
有興趣的可以自己新建一些復(fù)雜的繼承NSObject的對象看看內(nèi)存再根據(jù)源碼自己驗證分析一下
