iOS RunTime

Runtime

一、數(shù)據(jù)結(jié)構(gòu)

基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)

1、objc_object

id = objc_object : isa_t為共用體

objc_objcet

2、objc_class

Class = objc_class: Class也是對象,稱之為類對象,因為它繼承自onjc_object

objc_class

3、isa_t

有兩種類型,指針型isa、非指針型isa

isa_t
isa指向

4、cach_t

cach_t
cache_t

5、class_data_bits_t

class_data_bits_t

6、class_rw_t

例如分類1中添加的方法會在methods二維數(shù)組中的某個數(shù)組中存儲

class_rw_t

7、class_ro_t

name:類名,可以通過NSClassFromString(name)獲取該類

ivars:成員變量

properties:屬性

class_ro_t

8、method_t

Const char* types: 函數(shù)的返回和參數(shù)的組合

method_t

9、Type Encodings

第一個參數(shù)@代表一個對象,第一個參數(shù)和第二個參數(shù)是固定的,@代表的是誰調(diào)用的,也就是self,第二個:表達(dá)的是方法選擇器

Type Encodings

10、對象、類對象、元類對象

對象、類對象、元類對象

Root class指的就是NSObject

如果一個實例方法在元類對象以及根元類對象中都沒有,會查找根類對象中的同名實例方法,并調(diào)用。

指向

問題

[self class];

[super class];

[self class]
[super class]

二、消息傳遞

消息傳遞

1、緩存查找

哈希查找

哈希查找

2、在類對象中查找

類查找

3、父類逐級查找

父類逐級查找

4、消息轉(zhuǎn)發(fā)

消息轉(zhuǎn)發(fā)

a、動態(tài)解析

我們可以根據(jù)方法類型(實例方法or類方法)重寫一下方法,為類動態(tài)添加方法

+(BOOL)resolveInstanceMethod:(SEL)sel

+(BOOL)resolveClassMethod:(SEL)sel

在方法中調(diào)用一下方法來動態(tài)添加方法的實現(xiàn)

** 參數(shù)1:給哪個類添加

** 參數(shù)2:給哪個方法添加

** 參數(shù)3:方法的實現(xiàn)地址

** 參數(shù)4:方法的編碼類型

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

動態(tài)解析
動態(tài)解析

b、消息轉(zhuǎn)發(fā)

消息轉(zhuǎn)發(fā)分為兩步進(jìn)行: Fast forwarding和 Normal forwarding

1> Fast forwarding : 將消息轉(zhuǎn)發(fā)給一個其他的OC對象(找一個備用接收者)

重寫以下方法,返回一個其他對象即可

+/- (id)forwardingTargetForSelector:(SEL)aSelector

Fast forwarding

2> Normal forwarding : 實現(xiàn)一個完整的消息轉(zhuǎn)發(fā)過程

如果Fast forwarding沒有解決可以重寫以下兩個方法啟動完整的消息的轉(zhuǎn)發(fā)

+/- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

Runtime 會根據(jù)這個方法簽名,創(chuàng)建一個NSInvocation對象(NSInvocation封裝了未知消息的全部內(nèi)容,

包括:方法調(diào)用者 target、方法名 selector、方法參數(shù) argument 等),

然后調(diào)用第二個方法并將該NSInvocation對象作為參數(shù)傳入。

+/- (void)forwardInvocation:(NSInvocation *)invocation

在該方法中:將未知消息轉(zhuǎn)發(fā)給其它對象;改變未知消息的內(nèi)容(如方法名、方法參數(shù))再轉(zhuǎn)發(fā)給其它對象;甚至可以定義任何邏輯。

Normal forwarding

??如果第一個方法中沒有返回方法簽名,或者我們沒有重寫第二個方法,系統(tǒng)就會認(rèn)為我們徹底不想處理這個消息了,

這時候就會調(diào)用以下方法

+/- (void)doesNotRecognizeSelector:(SEL)sel

方法并拋出經(jīng)典的 crash:unrecognized selector sent to instance/class,結(jié)束 objc_msgSend 的全部流程。

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

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

  • runtime 和 runloop 作為一個程序員進(jìn)階是必須的,也是非常重要的, 在面試過程中是經(jīng)常會被問到的, ...
    SOI閱讀 22,025評論 3 63
  • Objective-C是基于C語言加入了面向?qū)ο筇匦院拖⑥D(zhuǎn)發(fā)機(jī)制的動態(tài)語言,這意味著它不僅需要一個編譯器,還需要...
    iOSCode閱讀 150評論 0 0
  • OC方法調(diào)用的本質(zhì):消息發(fā)送機(jī)制 - msg_Send. OC方法調(diào)用的本質(zhì)就是給對象發(fā)送消息:objc_msgS...
    蔣斌文閱讀 283評論 0 3
  • runtime 和 runloop 作為一個程序員進(jìn)階是必須的,也是非常重要的, 在面試過程中是經(jīng)常會被問到的, ...
    made_China閱讀 1,273評論 0 7
  • 一、數(shù)據(jù)結(jié)構(gòu):objc_object, objc_class, isa, class_data_bits_t, c...
    曼谷第一開膛手閱讀 300評論 0 0

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