OC對(duì)象的本質(zhì)

OC的對(duì)象 是基于C/C++的結(jié)構(gòu)體實(shí)現(xiàn)的(因?yàn)榻Y(jié)構(gòu)體里面可以存放各種不同類型的數(shù)據(jù))

如何查看cpp代碼
1.找到你所需要傳的文件的上一層文件夾 cd 到這個(gè)文件夾
2.clang -rewrite-objc main.m(你所需要轉(zhuǎn)的文件名稱) -o main.cpp(轉(zhuǎn)成什么樣的文件)
這種的是所有地方都可以運(yùn)行的cpp文件 很大
3. xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 輸出的CPP文件 這種是指定平臺(tái) 

一個(gè)NSObject對(duì)象占用多少內(nèi)存?

- 系統(tǒng)分配了16個(gè)字節(jié)給NSObject對(duì)象(通過malloc_size函數(shù)獲得)
- 但NSObject對(duì)象內(nèi)部只使用了8個(gè)字節(jié)的空間(64bit環(huán)境下,可以通過class_getInstanceSize函數(shù)獲得)
NSObject *obj = [[NSObject alloc] init];
//獲得NSObject類的實(shí)例對(duì)象的成員變量所占用的存儲(chǔ)空間的大小 
NSLog(@"%zd",class_getInstanceSize([NSObject class]));
//獲得objc指針?biāo)赶騼?nèi)存的大小
NSLog(@"%zd",malloc_size((__bridge const void *)(obj)));

iOS是小端模式 從高地址開始讀取數(shù)據(jù)
方法不存放在實(shí)例對(duì)象里面 實(shí)例對(duì)象存放他的成員變量
oc對(duì)象內(nèi)存分配都是16的倍數(shù)
sizeof 不是函數(shù) 是一個(gè)運(yùn)算符 在編譯器編譯的時(shí)候 就變成一個(gè)常數(shù) 在編譯的時(shí)候就確定的 不需要開辟空間

創(chuàng)建一個(gè)實(shí)例對(duì)象,至少需要多少內(nèi)存?
#import <objc/runtime.h>
class_getInstanceSize([NSObject class]);
創(chuàng)建一個(gè)實(shí)例對(duì)象,實(shí)際上分配了多少內(nèi)存?
#import <malloc/malloc.h>
malloc_size((__bridge const void *)obj);

OC對(duì)象的分類

1.instance對(duì)象 (實(shí)例對(duì)象)
2.class對(duì)象 (類對(duì)象)
3.meta-class對(duì)象 (元類對(duì)象)

instance對(duì)象

instance對(duì)象就是通過類alloc出來的對(duì)象 每次調(diào)用alloc都會(huì)產(chǎn)生新的instance對(duì)象
instance對(duì)象在內(nèi)存中存儲(chǔ)的信息包括
1.isa指針
2.其他成員變量

class對(duì)象

每個(gè)類在內(nèi)存中有且只有一個(gè)class對(duì)象
class方法返回的一直是class對(duì)象

 NSObject *object1 = [[NSObject alloc] init];
 Class objectClass = [object1 class];
 Class objectClass2 = object_getClass(object1);
 Class objectClass3 = [NSObject class];
class對(duì)象在內(nèi)存中存儲(chǔ)的信息包括
1.isa指針
2.superclass指針
3.類的屬性信息(@property) 類的對(duì)象方法信息(instance method)
4.類的協(xié)議信息(protocol)  類的成員變量信息(ivar)

meta-class對(duì)象(元類對(duì)象)

meta-data 元數(shù)據(jù) 描述數(shù)據(jù)的數(shù)據(jù)
每個(gè)類在內(nèi)存中有且只有一個(gè)meta-class對(duì)象
meta-class 對(duì)象 和 class 對(duì)象的內(nèi)存結(jié)構(gòu)是一樣的 但是 用途不一樣

//將類對(duì)象作為參數(shù)傳入 獲得元類對(duì)象
NSObject *object1 = [[NSObject alloc] init];
Class objectMetaClass = object_getClass([NSObject class]);
Class objectMetaClass1 = object_getClass([object1 class]);
meta-class對(duì)象在內(nèi)存中存儲(chǔ)的信息包括
1.isa指針
2.superclass指針
3.類的類方法信息(class method)

class_isMetaClass(objectMetaClass) 判斷是否為元類對(duì)象

object_getClass 和 objc_getClass 的區(qū)別
object_getClass
1.如果傳入實(shí)例對(duì)象  返回類對(duì)象
2.如果傳入類對(duì)象 返回meta-class對(duì)象
3.如果傳入meta-class對(duì)象 返回基類NSObject的meta-class對(duì)象
objc_getClass
傳入類名(字符串) 返回對(duì)應(yīng)的  類對(duì)象
-(Class) class 和 +(Class) class
返回類對(duì)象
對(duì)象方法的調(diào)用過程
- instance的isa指向class 
當(dāng)調(diào)用對(duì)象方法時(shí)  通過isa的找到class 最后找到對(duì)象方法的實(shí)現(xiàn)進(jìn)行調(diào)用
- class的isa指向meta-class
當(dāng)調(diào)用類方法時(shí) 通過class的isa找到meta-class 最后找到類方法的實(shí)現(xiàn)進(jìn)行調(diào)用
class對(duì)象的superclass指針
當(dāng)Student的instance對(duì)象要調(diào)用Person的對(duì)象方法時(shí),會(huì)先通過isa找到Student的class,然后通過superclass找到
Person的class,最后找到對(duì)象方法的實(shí)現(xiàn)進(jìn)行調(diào)用
meta-class對(duì)象的superclass指針
當(dāng)Student的class要調(diào)用Person的類方法時(shí),會(huì)先通過isa找到Student的meta-class,然后通過superclass找到
Person的meta-class,最后找到類方法的實(shí)現(xiàn)進(jìn)行調(diào)用
isa、superclass總結(jié)
instance的isa指向class

class的isa指向meta-class

meta-class的isa指向基類的meta-class

class的superclass指向父類的class
如果沒有父類,superclass指針為nil

meta-class的superclass指向父類的meta-class
基類的meta-class的superclass指向基類的class

instance調(diào)用對(duì)象方法的軌跡
isa找到class,方法不存在,就通過superclass找父類

class調(diào)用類方法的軌跡
isa找meta-class,方法不存在,就通過superclass找父類
流程圖 .png
獲取isa
MJPerson *person = [[MJPerson alloc] init];
p/x (long)person->isa

實(shí)例對(duì)象的isa & ISA_MASK 是類對(duì)象的地址值
類對(duì)象的isa & ISA_MASK 是元類對(duì)象的地址值

ISA_MASK的值.png

類對(duì)象superclass指針里面就是父類對(duì)象的地址值

對(duì)象的isa指針指向哪里?

- instance對(duì)象的isa指向class對(duì)象
- class對(duì)象的isa指向meta-class對(duì)象
- meta-class對(duì)象的isa指向基類的meta-clas對(duì)象

OC的類信息存放在哪里

- 對(duì)象方法 屬性 成員變量 協(xié)議信息 存放在class對(duì)象中
- 類方法 存放在meta-class對(duì)象中
- 成員變量的具體值 存放在instance對(duì)象中
內(nèi)存大小(64bit下).png

類對(duì)象和元類對(duì)象一直存放在內(nèi)存中 只有一份

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

相關(guān)閱讀更多精彩內(nèi)容

  • iOS底層原理總結(jié) - 探尋OC對(duì)象的本質(zhì) 原文鏈接 對(duì)小碼哥底層班視頻學(xué)習(xí)的總結(jié)與記錄。面試題部分,通過對(duì)面試題...
    二斤寂寞閱讀 721評(píng)論 0 4
  • iOS底層原理總結(jié) - 探尋OC對(duì)象的本質(zhì) 對(duì)小碼哥底層班視頻學(xué)習(xí)的總結(jié)與記錄。面試題部分,通過對(duì)面試題的分析探索...
    xx_cc閱讀 22,269評(píng)論 31 178
  • Objective-C中的對(duì)象,簡(jiǎn)稱OC對(duì)象,主要分為3種: instance對(duì)象(實(shí)例對(duì)象) class對(duì)象(類...
    Goose的小黃花閱讀 724評(píng)論 0 2
  • 炸看到這個(gè)標(biāo)題的時(shí)候,我驚呆了,仔細(xì)想了想,可以這么理解,如何有力的和上司溝通。以下的建議你可能會(huì)用到: 1.充分...
    纓絡(luò)閱讀 156評(píng)論 0 0
  • 多想再回到從前的時(shí)光 兩個(gè)人形影不離的好 沒有不能說的秘密 沒有不能問的心事 你的傷心我可以觸摸 我的未語是你的先...
    暗香盈夢(mèng)閱讀 445評(píng)論 2 1

友情鏈接更多精彩內(nèi)容