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)存中 只有一份