編寫高質量OC程式碼52建議總結:12.理解訊息轉發機制
訊息轉發分為兩個階段
--第一階段,先問接受者所屬的類,能否動態新增方法處理當前“未知的選擇器”,這叫做“動態方法解析”。
--第二階段,“完整的訊息轉發機制”,首先請接受者看看有沒有其他物件能處理這條訊息,如果有,則把訊息轉給那個物件,訊息轉發過程結束。如果沒有“備用接受者”,則啟動完整的訊息轉發機制,系統會把與訊息有關的所有細節封裝到 NSInvocation物件中,再給接受者最後一次機會處理當前訊息。
動態方法解析
該方法引數是那個未知的選擇器,返回值是bool型別,表示這個類是否能新增一個例項方法處理這個選擇器。有機會新增一個處理此選擇器的方法。如果未實現的方法不是例項方法而是類方法。執行期系統就會呼叫另一個方法。
備註:使用這種方法的前提是,相關實現程式碼已經寫好,只等執行時動態插在類裡。
備用接受者
當前接受者還有第二次機會處理未知的選擇器。能不能把這條訊息轉給其他物件處理。
在一個物件內部,可能還有一系列其他物件,該物件可經由此方法將能夠處理某選擇子的相關內部物件返回。
備註:在這一步,無法操作所轉發的訊息。
完整的訊息轉發
首先建立NSInvocation物件,把尚未處理的訊息所有相關細節都封裝其中。包含選擇器、目標、引數。
實現方式:在觸發訊息前,先以某種方式改變訊息內容,比如,追加另外一個引數,或者改變選擇器。
實現此方法時,如果發現呼叫操作不應該由本類操作,則呼叫父類同名方法。繼承體系中每個類都有機會處理此呼叫請求,直到NSObject。最後呼叫了NSObject類的方法,該方法會繼續呼叫“doesNotRecognizeSelector:”,丟擲異常,代表訊息最終未被處理。
訊息轉發全流程
步驟越往後,處理訊息的代價越大。最好能在第一步處理完,執行期系統就可以將此方法快取。第三部只是修改了呼叫目標,這項改動放在第二步會更簡單,不然的話,還得建立並處理完整的NSInvocation。
總結:
--1.若物件無法響應某個選擇子,則進入訊息轉發流程。
--2.通過執行期的動態方法解析功能,我們可以在需要用到某個方法時再將其加入類中。
--3.物件可以把其無法解讀的某些選擇子轉交給其他物件來處理。
--4.如果還沒辦法處理選擇子,那就啟動完整的訊息轉發機制。
--第一階段,先問接受者所屬的類,能否動態新增方法處理當前“未知的選擇器”,這叫做“動態方法解析”。
--第二階段,“完整的訊息轉發機制”,首先請接受者看看有沒有其他物件能處理這條訊息,如果有,則把訊息轉給那個物件,訊息轉發過程結束。如果沒有“備用接受者”,則啟動完整的訊息轉發機制,系統會把與訊息有關的所有細節封裝到 NSInvocation物件中,再給接受者最後一次機會處理當前訊息。
動態方法解析
+(BOOL)resolveInstanceMethod:(SEL)sel
該方法引數是那個未知的選擇器,返回值是bool型別,表示這個類是否能新增一個例項方法處理這個選擇器。有機會新增一個處理此選擇器的方法。如果未實現的方法不是例項方法而是類方法。執行期系統就會呼叫另一個方法。
+(BOOL)resolveClassMethod:(SEL)sel
備註:使用這種方法的前提是,相關實現程式碼已經寫好,只等執行時動態插在類裡。
備用接受者
當前接受者還有第二次機會處理未知的選擇器。能不能把這條訊息轉給其他物件處理。
-(id)forwardingTargetForSelector:(SEL)aSelector
在一個物件內部,可能還有一系列其他物件,該物件可經由此方法將能夠處理某選擇子的相關內部物件返回。
備註:在這一步,無法操作所轉發的訊息。
完整的訊息轉發
首先建立NSInvocation物件,把尚未處理的訊息所有相關細節都封裝其中。包含選擇器、目標、引數。
-(void)forwardInvocation:(NSInvocation *)anInvocation
實現方式:在觸發訊息前,先以某種方式改變訊息內容,比如,追加另外一個引數,或者改變選擇器。
實現此方法時,如果發現呼叫操作不應該由本類操作,則呼叫父類同名方法。繼承體系中每個類都有機會處理此呼叫請求,直到NSObject。最後呼叫了NSObject類的方法,該方法會繼續呼叫“doesNotRecognizeSelector:”,丟擲異常,代表訊息最終未被處理。
訊息轉發全流程
步驟越往後,處理訊息的代價越大。最好能在第一步處理完,執行期系統就可以將此方法快取。第三部只是修改了呼叫目標,這項改動放在第二步會更簡單,不然的話,還得建立並處理完整的NSInvocation。
總結:
--1.若物件無法響應某個選擇子,則進入訊息轉發流程。
--2.通過執行期的動態方法解析功能,我們可以在需要用到某個方法時再將其加入類中。
--3.物件可以把其無法解讀的某些選擇子轉交給其他物件來處理。
--4.如果還沒辦法處理選擇子,那就啟動完整的訊息轉發機制。
相關文章
- 我總結了寫出高質量程式碼的12條建議
- 編寫高質量程式碼 改善Python程式的91個建議Python
- 《編寫高質量程式碼:改善Java程式的151個建議》筆記Java筆記
- iOS 編寫高質量Objective-C程式碼iOSObjectC程式
- [Unity 程式碼寫法整理]訊息機制(三)Unity
- iOS編寫高質量Objective-C程式碼(六)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(七)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(八)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(六)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(五)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(一)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(二)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(四)iOSObjectC程式
- iOS編寫高質量Objective-C程式碼(四)iOSObjectC程式
- iOS編寫高質量Objective-C程式碼(二)iOSObjectC程式
- iOS 編寫高質量Objective-C程式碼(三)iOSObjectC程式
- 如何編寫高質量的C#程式碼(一)C#
- [轉載]程式設計師必備:書寫高質量SQL的30條建議程式設計師SQL
- 理解 Android 訊息機制Android
- OC訊息機制和super關鍵字
- 書寫高質量sql的一些建議SQL
- 用程式碼理解 ObjC 中的傳送訊息和訊息轉發OBJ
- Runtime 從NullSafe原始碼看訊息轉發 機制Null原始碼
- Github即將破百萬的PDF:編寫高質量程式碼改善JAVA程式的151個建議GithubJava
- iOS 編寫高質量Objective-C程式碼(一)—— 簡介iOSObjectC程式
- 我們應該如何編寫高質量的前端程式碼前端
- iOS 訊息轉發機制Demo解析iOS
- 🐒編寫高質量程式碼(手撕程式碼)
- 總結 90 條寫 Python 程式的建議Python
- 每日10行程式碼52:編寫高質量python程式碼方法4——用輔助函式來取代複雜的表示式行程Python函式
- mysql鎖機制總結,以及優化建議MySql優化
- 《Effective JavaScript 編寫高質量JavaScript程式碼的68個有效方法》JavaScript
- iOS進階之訊息轉發機制iOS
- 深入理解Android訊息機制Android
- 深入理解windows 訊息機制Windows
- 編寫靈活、穩定、高質量的HTML程式碼的規範HTML
- 編寫靈活、穩定、高質量的CSS程式碼的規範CSS
- 消除程式碼中的壞味道,編寫高質量程式碼
- 高頻考點,六大程式通訊機制總結