二、在OC中的全部面向對象的實現,都是基於C/C++的數據結構實現的數據結構
三、將Objective-C代碼轉換爲C\C++代碼架構
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 輸出的CPP文件框架
注:若是須要連接其餘框架,使用-framework參數。好比-framework UIKitiphone
NSObject基類的實現:佈局
子類的實現:spa
子類的拆解:3d
一、在OC中的對象,就是 C++中的 struct來實現的指針
二、每一個OC對象中都會有一個 isa 的指針,isa指向的是 objc_class 結構體,以下(舊版OC原碼):code
經過代碼能夠看得出在OC2 中已經不能經過 objc_method_list 之類的方式獲取方法名、實例、協議之類的了,須要使用新的方法獲取視頻
思路:自定義一個和oc源碼中 objc_class 結構同樣的結構體,而後將對象的isa 強轉成咱們自定義的那個,再去調用
以下是OC中objc_class的源碼(新版OC原碼):
新的OC版本中方法、屬性、協議相關數據都存在了 bits
經過 bits.data() 返回 class_rw_t 結構,以下:
bits.data() 的實現:
其中須要 經過 & FAST_DATA_MASK 才能獲取到真實的地址
Objective-C對象主要分爲如下3類:
1> instance對象(實例對象)
2> class對象(類對象)存儲實例方法列表等信息
3> meta-class對象(元類對象)存儲類方法列表等信息
經過下面的代碼能夠分別獲取3種對象:
NSObject* obj = [[NSObject alloc]init]; const char* className = [@"NSObject" cStringUsingEncoding:NSUTF8StringEncoding]; // 實例對象 NSLog(@"instance: %p",obj); // 類對象 NSLog(@"NSObject class: %p", [NSObject class]); // 同上 NSLog(@"obj class: %p", [obj class]); // 若是傳實例對象,獲取到的仍是類對象 NSLog(@"get class: %p", object_getClass(obj)); // 經過類名獲取類對象 NSLog(@"objcClass: %p", objc_getClass(className)); // 元類對象 // 必須要傳入類對象才能獲取元類對象 NSLog(@"meta-class: %p", object_getClass([obj class])); // 經過類名獲取元類對象 NSLog(@"objcMetaClass: %p", objc_getMetaClass(className)); // 判斷是不是metaClass NSLog(@"isMetaClass1:%i",class_isMetaClass([NSObject class])); // 0 NSLog(@"isMetaClass2:%i",class_isMetaClass([[NSObject class] class])); // 0 NSLog(@"isMetaClass3:%i",class_isMetaClass(object_getClass([NSObject class]))); // 1
輸出:
2018-09-27 14:39:37.363 OC_isa_supclass[1350:102454] instance: 0x100202b50 2018-09-27 14:39:37.364 OC_isa_supclass[1350:102454] NSObject class: 0x7fff760140f0 2018-09-27 14:39:37.364 OC_isa_supclass[1350:102454] obj class: 0x7fff760140f0 2018-09-27 14:39:37.364 OC_isa_supclass[1350:102454] get class: 0x7fff760140f0 2018-09-27 14:39:37.365 OC_isa_supclass[1350:102454] objcClass: 0x7fff760140f0 2018-09-27 14:39:37.365 OC_isa_supclass[1350:102454] meta-class: 0x7fff76014118 2018-09-27 14:39:37.365 OC_isa_supclass[1350:102454] objcMetaClass: 0x7fff76014118
2018-09-27 14:49:27.746 OC_isa_supclass[1360:106109] isMetaClass1:0
2018-09-27 14:49:27.746 OC_isa_supclass[1360:106109] isMetaClass2:0
2018-09-27 14:49:27.746 OC_isa_supclass[1360:106109] isMetaClass3:1
1> 須要注意的是 object_getClass 方法,當傳入的是實例對象,就會返回類對象,若是傳入的是類對象就會返回元類對象
2> 還有一點就是 [[NSObject class] class] 這樣是獲取不到元類對象的,這樣獲取到的仍是類對象
3> 另外裏面還有兩個 objc_ 開頭的方法,分別是獲取類對象和元類對象,但它是傳入類名字符串就能夠了,須要轉換成 C語言的char
一、instance對象
它們是不一樣的兩個對象,分別佔據着兩塊不一樣的內存
instance對象在內存中保存的信息包括:
1> isa指針
2> 其它成員變量
二、class對象
NSObject類對象只有一個,全部實例對象的class屬性獲取到的都是同一個類對象
class對象在內存中存儲的信息主要包括:
1> isa指針
2> superclass指針
3> 類的屬性信息(@property)、類的對象方法信息(instance method)
4> 類的協議信息(protocol)、類的成員變量信息(ivar)
....
三、meta-class對象
每一個類在內存中有且只有一個meta-class對象
meta-class對象在內存中存儲的信息主要包括:
1> isa指針
2> superclass指針
3> 類的類方法信息(class method)
...
注:class 對象和 meta-class 對象都是 Class 類型的,它們其實結構都是同樣的,class對象中同樣會包含 類方法,只不過那個類方法是 空的而已。
一樣,meta-class對象中也有 類的屬性、對象方法、協議、成員變量,不過那些對應的值也都是空
上面咱們經過源碼能夠看到每一個對象都有一個 isa 指針,isa指針做用是幹嗎的呢?
經過上圖能夠看出:
1> instance的isa指向class
當調用對象方法時,經過instance的isa找到class,最後找到對象方法的實現進行調用
2> class的isa指向meta-class
當調用類方法時,經過class的isa找到meta-class,最後找到類方法的實現進行調用
superclass是用於找父類的,好比子類調用某個方法,若是子類中沒有,就會去父類找,底層就是經過superclass找到父類的,以下圖:
當Student的instance對象要調用Person的對象方法時,會先經過isa找到Student的class,而後經過superclass找到Person的class,最後找到對象方法的實現進行調用
meta-class中的superclass基本和 class對象中的同樣,不過有一點點區別,如圖:
當Student的class要調用Person的類方法時,會先經過isa找到Student的meta-class,而後經過superclass找到Person的meta-class,最後找到類方法的實現進行調用
有什麼區別呢?從這圖可能看不出來,區別就是若是基類的meta-class中都找不到類方法,那麼它就會去從基類對象裏面去找對象方法,OC的底層實際上是不區分 對象方法與類方法的。
這張圖可以清楚的描述 isa和superclass的做用和關係,下面是備註了一下,看得更加懂點。
instance調用對象方法的軌跡:
實例對象會先經過isa找到class對象,判斷裏面有沒有要調用的方法,若是有就直接調用,沒有就會經過class對象中的superclass找到父類,而後在父類中判斷是否有該方法,若是尚未就接着往上找。
class調用類方法的軌跡:
isa找meta-class,方法不存在,就經過superclass找父類,最後基類mate-class也沒有的話還會去基類對象找,這樣就會致使調用類方法可能會去調用實例對象的方法
上面已經說到了instance對象的isa指針指向的是class對象,那就是說instance對象的isa指針內存地址是否是就是class對象的內存地址呢?
若是在之前的32位系統中確實如此,在64位系統中不是的,裏面有一個點操做, ISA_MASK
其中arm64和x86架構的這個 ISA_MASK的偏移地址是不同的,以下圖:
class、meta-class對象的本質結構都是struct objc_class,以下圖:
-----------------------------
本文參考借鑑MJ的教程視頻,很是感謝.