Objective-C的本質(zhì)
我們平時編寫的Objective-C代碼,底層實現(xiàn)其實都是C\C++代碼力惯,所以Objective-C的面向?qū)ο蠖际腔贑\C++的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的熏矿。
如何將Objective-C代碼轉(zhuǎn)換為C\C++代碼供搀?
//如果需要鏈接其他框架鞋囊,使用-framework參數(shù)止后。比如-framework UIKit
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 輸出的CPP文件
OC對象的本質(zhì)
NSObject的底層實現(xiàn)
為了方便理解所以直接寫Class類,其實是個結(jié)構(gòu)體:
struct NSObject_IMPL NSObject_IVARS
如何實時查看內(nèi)存數(shù)據(jù)
Debug -> Debug Workfllow -> View Memory (Shift + Command + M)OC對象的分類
1溜腐、instance對象(實例對象)
instance對象就是通過類alloc出來的對象译株,每次調(diào)用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指針和其他成員變量望众。
2匪补、class對象(類對象)
NSObject *object1 = [[NSObject alloc] init];
Class objectClass1 = [object1 class];
Class objectClass2 = object_getClass(object1); //Runtime API
objectClass1和objectClass2都是NSObject的class對象(類對象),每個類在內(nèi)存中有且只有一個class對象。
class對象在內(nèi)存中存儲的信息主要包括:isa指針烂翰、superclass指針夯缺、類的屬性信息(@property)、類的對象方法信息(instance method)甘耿、類的協(xié)議信息(protocol)踊兜、類的成員變量信息(ivar)
3、meta-class對象(元類對象)
Class objectMetaClass = object_getClass([NSObject class]); //Runtime API
objectMetaClass是NSObject的meta-class對象(元類對象),每個類在內(nèi)存中有且只有一個meta-class對象棵里。
class對象在內(nèi)存中存儲的信息主要包括:isa指針润文、superclass指針、類的類方法信息(class method)
isa殿怜、superclass總結(jié)
1典蝌、instance的isa指向class
2、class的isa指向meta-class
3头谜、meta-class的isa指向基類的meta-class
4骏掀、class的superclass指向父類的class,如果沒有父類,superclass指針為nil
5截驮、meta-class的superclass指向父類的meta-class笑陈,基類的meta-class的superclass指向基類的class
6、instance調(diào)用對象方法的軌跡:isa找到class葵袭,方法不存在涵妥,就通過superclass找父類
7、class調(diào)用類方法的軌跡:isa找meta-class坡锡,方法不存在蓬网,就通過superclass找父類
窺探struct objc_class的結(jié)構(gòu)
class帆锋、meta-class對象的本質(zhì)結(jié)構(gòu)都是struct objc_class
class_rw_t
class_rw_t里面的methods、properties禽额、protocols是二維數(shù)組锯厢,是可讀可寫的,包含了類的初始內(nèi)容脯倒、分類的內(nèi)容实辑。
class_ro_t
class_ro_t里面的baseMethodList、baseProtocols盔憨、ivars徙菠、baseProperties是一維數(shù)組,是只讀的郁岩,包含了類的初始內(nèi)容婿奔。
method_t
method_t是對方法\函數(shù)的封裝。
IMP代表函數(shù)的具體實現(xiàn)问慎。
SEL代表方法\函數(shù)名萍摊,一般叫做選擇器,底層結(jié)構(gòu)跟char *類似如叼。
可以通過@selector()和sel_registerName()獲得冰木。
可以通過sel_getName()和NSStringFromSelector()轉(zhuǎn)成字符串。
不同類中相同名字的方法笼恰,所對應的方法選擇器是相同的踊沸。
types包含了函數(shù)返回值、參數(shù)編碼的字符社证。
方法緩存
Class內(nèi)部結(jié)構(gòu)中有個方法緩存(cache_t),用散列表(哈希表)來緩存曾經(jīng)調(diào)用過的方法追葡,可以提高方法的查找速度腺律。