Objective-C的本質(zhì)
-
Objective-C代碼蓝丙,底層實習(xí)都是C\C++代碼;
Objective-C編譯 - 所以O(shè)bjective-C的面相對象都是基與C\C++的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的。
- 如何將Objective-C轉(zhuǎn)成C\C++代碼晤硕。
xcrun -sdk iphones clang -arch arm64 -rewrite-objc OC源碼文件 輸出的CPP文件
如果需要鏈接其他框架渠退,使用-framework 參數(shù)块仆。eg -framework UIKit
OC對象的本質(zhì)
NSObject的底層實現(xiàn)
OC對象的本質(zhì)就是一個結(jié)構(gòu)體。
struck NSObject_IPML{
Class isa;
}
@interface NSObject{
Class isa;
}
typedef struct objc_class *Class;
OC 對象內(nèi)存空間
-
創(chuàng)建一個實例對象翩迈。多少內(nèi)存
#import <objc/runtime.h> class_getInstanceSize([NSObject class]);
我們可以看到打印出來是8個字節(jié)持灰,因為在內(nèi)存中,這個對象可以看做是一個結(jié)構(gòu)題负饲,這個結(jié)構(gòu)體中只有Class isa 堤魁,Class 就是 typedefe struct object_class * Class這個就是一個指針,一個指針在64位系統(tǒng)中占8個字節(jié)返十。
-
創(chuàng)建一個實例對象妥泉,實際上分配了多少內(nèi)存
#import<malloc/malloc.h> malloc_size((__bridge const void*)obj);
這里得到的值是16個字節(jié),為什么是16個字節(jié)呢洞坑,看源碼如圖
在源碼中通過上面的分析aligneInstanceSize()的長度為8.extraBytes 的長度為0. 然后系統(tǒng)當(dāng)size 小于8的時候會改成16.(其實這里也設(shè)計到內(nèi)存對齊的問題)盲链。
OC對象的分類
- instance 對象(實例對象)
- class 對象 (類對象)
- meta-class對象(云對象)
instace對象
-
instance 對象就是通過類alloc出來的對象,每次alloc都會產(chǎn)生新的instance對象迟杂。
NSObject * object1 =[[NSObject alloc]init]; NSObject * object2 =[[NSObject alloc]init];
object1,object2是NSObject的instance對象(實例對象);
他們是不同的兩個對象刽沾,分別占據(jù)不同的內(nèi)存。
instance 對象在內(nèi)旋中存儲的信息包括排拷。
isa 指針
其他成員變量
Class 對象
NSObject * object1 =[NSObject alloc]init];
NSObject * object2 =[NSObject alloc]init];
Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = [NSObject class];
Class objectClass4 = object_getClass(object1);
Class objectClass5 = object_getClass(object2);
object1 到object5 都是NSObjectClass 的class 對象侧漓。(類對象)
他們是同一個對象,每個類在內(nèi)存中只有一個class 對象监氢。
calss 對象在內(nèi)存中的信息主要包括
isa 指針
superclass 指針
類的屬性信息(@property)類的對象方法信息(instance method)布蔗;
類的協(xié)議信息(protocol)類的成員變量嘻嘻(ivar)
meta-class
Class objectMeataClass = object_getClass([NSObject class]);
objectMeataClass 是NSObject的meta-class對象藤违。
每個類在內(nèi)存中有且只有一個meta-class 對象。
meta-class 對象和class對象結(jié)構(gòu)是一樣的纵揍,但是用途不一樣顿乒,在內(nèi)存中存儲的信息主要包括
isa指針
superclass 指針
類的類方法信息(class method )
怎么檢查Class 是否為meta-class
#import <objc/runtime.h>
BOOL result = class_isMetaClass([NSObject class]);
isa 指針
instance 的isa 指向class
當(dāng)調(diào)用對象方法時,通過instance的isa 找到class 泽谨,最后找到對象方法的實現(xiàn)調(diào)用璧榄。
class 的isa指向meta-class
當(dāng)調(diào)用類方法時,通過class 的的isa指針找到meta-class 隔盛,最后找到類方法的實現(xiàn)調(diào)用犹菱。
class 對象的superclass指針
當(dāng)Student 的instace對象要調(diào)用Person的對象方法時,回先通過isa找到Student的class吮炕,然后通過superclass找到person的class ,最后執(zhí)行找到對象方法的實現(xiàn)進行調(diào)用访得。
meta-class 對象的superclass
當(dāng)Sutdent的class要調(diào)用Persion類方法時龙亲,回先通過isa找到Student的meta-class,然后通過superclass周到Person的meta-class悍抑,最后到類方法中的實現(xiàn)進行調(diào)用
isa superclass 總結(jié)
- instace isa 指向class
- class isa 指向 meta-class
- meta-class指向基類的meta-class
*class的superclass 指向父類的class 如果沒有父類鳄炉,superclass指針為nil
- meta-class 的superclass 指向父類的meta-class,基類的meta-class的superclass指向基類的class
*instance 調(diào)用對象方法的軌跡
isa 找class搜骡,方法不存在通過fuperclass 找到父類 - class 調(diào)用類方法的軌跡
isa 找到meta-class 拂盯,方法不存在,就通過superclass 找到父類记靡。