OC訊息機制,訊息轉發機制

weixin_34236497發表於2016-08-21

Runtime簡稱執行時,其中最主要的是訊息機制

概述 C 與 OC 的不同

1.C 語言,函式的呼叫在編譯的時候就會決定呼叫哪個函式(C語言的函式呼叫),編譯完成之後直接順序執行,無任何二義特性.

2.OC函式的呼叫成為訊息傳送,屬於動態呼叫的過程,在編譯的時候並不能決定真正呼叫哪個函式(其實的過程是,在編譯階段,OC可以呼叫任何函式,即使這個函式並未實現呢,只要申明過就不會報錯,而C語言在編譯階段就會報錯),只有在真正執行的時候才會根據函式的名稱找到對應的函式來呼叫

3.簡述內部實現的過程

1>首先,在編譯器將程式碼[obi makeText] -> 轉換成objc_msgSend(obj,@selector(makeText));

2>在objc-msgSend函式中,首先通過obj的isa指標找到obj對應的class,在Classe中先去cache中通過SEL查詢對應函式method(猜測cache中method列表是以SEL為key,通過hash表示儲存的,這樣能提高函式查詢速度)

3>若在cache中未找到,再去methodList中查詢,若在methodList中未找到,則取superClass中查詢,若能找到,則將method加入到cache中,以方便下次查詢,並通過method中的函式指標跳轉到對應的函式中去執行


二.訊息轉發(可以間接實現多重繼承)

注意:當向someObject傳送訊息的時候,runtime System在當前類和父類中找不到對應方法的實現

時,runtime system並不會立即報錯使程式崩潰,而是一次執行

會執行下面的順序

在本類及父類中找不到方法

1>動態方法解析:向當前類傳送resloveInstanceMethod:訊號,檢查是否動態向該類新增了方法

2>快速訊息轉發:當前面沒有實現的時候,檢查該類是否實現了forwardingTargeetForSelector:方法:若實現了則呼叫這個方法,若該方法返回值物件非nil或非Self,則該返回物件重新傳送訊息

- (id)forwardingTargetForSelector:(SEL)aSelector

{

�class*other = [classnew];if([other forwardingTargetForSelector:aSelector]) {returnother;

}else{return[super forwardingTargetForSelector:aSelector];

}

}

3>標準資訊轉發:runTime傳送methodSignatureForSelector:訊息獲取Selector對應的方法簽名,返回值非空則通過forwardInvocation:轉發訊息,返回值為空則向當前物件傳送doesNotRecongizeSelector:訊息,程式崩潰退出




相關文章