OC物件的本質

weixin_34320159發表於2018-06-05

一個NSObject物件佔用多少記憶體?

由這個問題可以引出更多底層的東西。在這裡要搞清楚NSObject物件在記憶體中的佈局,就要明白OC物件的本質。

3014185-67f5e46913b25f77.png
Objective-C的本質

那麼如何將Objective-C程式碼轉換成C\C++程式碼呢?

直接用命令列轉換
clang -rewrite-objc main.m -o main.cpp
區分平臺 轉成相對應平臺的c++檔案
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc mian.m -o main-arm64.cpp

3014185-dd714d11bc815460.png
不同平臺區分

檢視本質
3014185-b87f82525d5202b1.png
本質

圖上可以看出OC物件的本質就是結構體,那麼結構體在記憶體中佔的大小分別是8個位元組(64位系統)、4個位元組(32位系統)。
問:一個NSObject物件是不是也是8個位元組(預設64位的)?

通過程式碼檢視一下:

NSObject *obj = [[NSObject alloc]init];
 //獲取NSObject類的例項物件的成員變數所佔用的大小>>8 至少需要多少位元組
NSLog(@"%zd",class_getInstanceSize([NSObject class]));//8個位元組
 //獲得obj指標指向記憶體的大小>>16  實際分配了多少記憶體
NSLog(@"%zd",malloc_size((__bridge const void*)obj));//16個位元組

蘋果原始碼網站

答案:16個位元組
  • 系統分配了16個位元組的空間給NSObject物件(通過malloc_size函式獲得)
  • 但是NSObject物件內部只使用了8個位元組空間(64bit環境下,通過class_getInstanceSize函式獲得)
  • 檢視原始碼可以看到,Core Foundation 框架規定最小是16個位元組
size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }
3014185-0573ba64d73dd62b.png
佔用圖比

新建一個Student類並申明兩個成員變數檢視它的底層結構


3014185-1e68e802ff42c2fb.png
Student類底層結構

3014185-c8bede269e615f83.png
答案:都是16個位元組

記憶體對齊:結構體的大小必須是最大成員大小的倍數
iOS分配記憶體空間都是16的倍數。例如你需要24個位元組,但是系統會分配32個位元組
sizeof():相當於運算子,不是一個函式,編譯時已確定值

3014185-b7a7cbc78991306e.png
OC物件

3014185-80942b5a968f9b61.png
instance

3014185-c18945d84185a411.png
class

3014185-d229da35eb2c8655.png
meta-class

3014185-b06e6bfe079a192f.png
object_getClass

3014185-b89b58e523150837.png
三個class的區別

3014185-079ecbee226821f6.png
三者裡面的組成結構

物件的isa指標指向哪裡?

3014185-503f505cae01f65a.png
isa的指向

3014185-7c448a6137d3945a.png
class物件的superclass的指向

3014185-de362ccd67d127f4.png
meta-class物件的superclass的指向

3014185-dfc66541bfdfdfc4.png
isa指標指向

3014185-d7c3e25f3970949f.png
isa、superclasaa的總結

3014185-f9db925cfa49d0d2.png
窺探struct objc_class的結構

答案:

  • instance物件的isa指向class物件
  • class物件的isa指向meta-class物件
  • meta-class的isa指向基類的meta-class物件

OC的類資訊存放在哪裡?

答案:

  • 物件方法、屬性、成員變數資訊(名字 型別等)、協議資訊存在在class物件中
  • 類方法存放在meta-class物件中
  • 成員變數的具體值,存放在instance物件中

相關文章