Runtime初涉之消息轉(zhuǎn)發(fā)

一柔昼、消息轉(zhuǎn)發(fā)機(jī)制

當(dāng)向某個對象發(fā)送一條消息時垂券,若該對象的方法列表以及它相應(yīng)繼承鏈上的方法列表都無法找到以該消息選擇子作為key的方法實現(xiàn)時侨艾,則會觸發(fā)消息轉(zhuǎn)發(fā)機(jī)制执虹。

1、動態(tài)方法解析


+ (BOOL)resolveInstanceMethod:(SEL)sel;

首先唠梨,當(dāng)接受到未能識別的選擇子時袋励,運行時系統(tǒng)會調(diào)用該函數(shù)用以給對象一次機(jī)會來添加相應(yīng)的方法實現(xiàn),如果用戶在該函數(shù)中動態(tài)添加了相應(yīng)方法的實現(xiàn)当叭,則跳轉(zhuǎn)到方法的實現(xiàn)部分茬故,并將該實現(xiàn)存入緩存中,以供下次調(diào)用蚁鳖。

2磺芭、備援接收者


- (id)forwardingTargetForSelector:(SEL)aSelector;

如果運行時在消息轉(zhuǎn)發(fā)的第一步中未找到所調(diào)用方法的實現(xiàn),那么當(dāng)前接收者還有第二次機(jī)會進(jìn)行未知選擇子的處理醉箕。這時運行期系統(tǒng)會調(diào)用上述方法钾腺,并將未知選擇子作為參數(shù)傳入徙垫,該方法可以返回一個能處理該選擇子的對象,運行時系統(tǒng)會根據(jù)返回的對象進(jìn)行查找放棒,若找到則跳轉(zhuǎn)到相應(yīng)方法的實現(xiàn)姻报,則消息轉(zhuǎn)發(fā)結(jié)束。

3间螟、完整的消息轉(zhuǎn)發(fā)


- (void)forwardInvocation:(NSInvocation *)anInvocation;

當(dāng)運行時系統(tǒng)檢測到第二步中用戶未返回能處理相應(yīng)選擇子的對象時吴旋,那么來到這一步就要啟動完整的消息轉(zhuǎn)發(fā)機(jī)制了。該方法可以改變消息調(diào)用目標(biāo)厢破,運行時系統(tǒng)根據(jù)所改變的調(diào)用目標(biāo)荣瑟,向調(diào)用目標(biāo)方法列表中查詢對應(yīng)方法的實現(xiàn)并實現(xiàn)跳轉(zhuǎn),這種方式和第二步的操作非常相似溉奕。當(dāng)然你也可以修改方法的選擇子褂傀,亦或者向所調(diào)用方法中追加一個參數(shù)等來跳轉(zhuǎn)到相關(guān)方法的實現(xiàn)。

最后加勤,如果消息轉(zhuǎn)發(fā)的第三步還未能處理該未知選擇子的話仙辟,那么最終會調(diào)用NSObject類的如下方法用以異常的拋出,表明該選擇子最終未能處理鳄梅。


- (void)doesNotRecognizeSelector:(SEL)aSelector;

下面附上完整的消息轉(zhuǎn)發(fā)流程圖:


二叠国、消息轉(zhuǎn)發(fā)驗證

好了,看了那么多的理論知識戴尸,相比大家也已經(jīng)累了粟焊,那我們用一個實例來具體說明Runtime的消息轉(zhuǎn)發(fā)機(jī)制吧。我是傳送門~~~

首先新建一個工程孙蒙,并在工程中添加Cat项棠、Dog and Chicken三個類,并在每個類的.h文件中聲明jump方法挎峦,在Cat.m文件中聲明消息轉(zhuǎn)發(fā)的第一步方法:resolveInstanceMethod: 香追,在該方法中動態(tài)添加jump方法的實現(xiàn)。


消息轉(zhuǎn)發(fā)第一步

注:在第一步中動態(tài)添加方法實現(xiàn)用到了Runtime中的class_addMethod方法坦胶,該方法用以向該類的實例對象中添加相應(yīng)的方法實現(xiàn)透典。

然后在main.m文件中調(diào)用Cat實例的jump方法,就會看到在控制臺打印出如下結(jié)果:


消息轉(zhuǎn)發(fā)第一步打印結(jié)果

然后在Dog.m文件中驗證消息轉(zhuǎn)發(fā)第二步過程顿苇,為了讓運行時系統(tǒng)能夠運行到forwardingTargetForSelector:方法峭咒,我們先在resolveInstanceMethod:中返回NO,代碼如下:


消息轉(zhuǎn)發(fā)第二步

然后按照之前的樣子纪岁,在main.m文件中讓Dog也jump起來凑队,運行之后打印結(jié)果如下:


消息轉(zhuǎn)發(fā)第二步打印結(jié)果

最后我們來驗證消息轉(zhuǎn)發(fā)第三步驟的過程。

在最后的Chicken.m文件中我們讓前兩步的方法分別返回NO和nil值幔翰,用以快速觸發(fā)消息轉(zhuǎn)發(fā)機(jī)制中的完整消息轉(zhuǎn)發(fā)機(jī)制顽决。在驗證這一步中我們注意到短条,在調(diào)用forwardInvocation:方法之前我們需要實現(xiàn)methodSignatureForSelector:方法导匣,并將相應(yīng)選擇子的描述返回才菠。


消息轉(zhuǎn)發(fā)第三步

這里我用了改變調(diào)用目標(biāo)這種方式進(jìn)行消息轉(zhuǎn)發(fā)機(jī)制,至于改換選擇子贡定,讀者可以自行嘗試運行哈赋访,具體我已在項目代碼中寫明,最終調(diào)用Chicken實例的jump方法缓待,其打印結(jié)果如下:


消息轉(zhuǎn)發(fā)第三步打印結(jié)果

明明分別調(diào)用了三個動物的jump蚓耽,最后在控制臺只看到了Cat一直在jump。旋炒。步悠。

如果有覺得上述我講的不對的地方歡迎指出,大家多多交流溝通瘫镇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鼎兽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铣除,更是在濱河造成了極大的恐慌谚咬,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尚粘,死亡現(xiàn)場離奇詭異择卦,居然都是意外死亡倍啥,警方通過查閱死者的電腦和手機(jī)畜眨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盗棵,“玉大人泽铛,你說我怎么就攤上這事尚辑。” “怎么了厚宰?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵腌巾,是天一觀的道長。 經(jīng)常有香客問我铲觉,道長澈蝙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任撵幽,我火速辦了婚禮灯荧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盐杂。我一直安慰自己逗载,他們只是感情好哆窿,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著厉斟,像睡著了一般挚躯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擦秽,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天码荔,我揣著相機(jī)與錄音,去河邊找鬼感挥。 笑死缩搅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的触幼。 我是一名探鬼主播硼瓣,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼置谦!你這毒婦竟也來了堂鲤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤霉祸,失蹤者是張志新(化名)和其女友劉穎筑累,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丝蹭,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡慢宗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了奔穿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镜沽。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贱田,靈堂內(nèi)的尸體忽然破棺而出缅茉,到底是詐尸還是另有隱情,我是刑警寧澤男摧,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布蔬墩,位于F島的核電站,受9級特大地震影響耗拓,放射性物質(zhì)發(fā)生泄漏拇颅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一乔询、第九天 我趴在偏房一處隱蔽的房頂上張望樟插。 院中可真熱鬧,春花似錦、人聲如沸黄锤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸵熟。三九已至副编,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旅赢,已是汗流浹背齿桃。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留煮盼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓带污,卻偏偏與公主長得像僵控,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鱼冀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 與上次發(fā)文間隔也有很長一段時間了报破,由于各種原因,沒有及時擬寫文章(好吧千绪,我又矯情了)充易,話不多說,咱們進(jìn)入正題荸型。 上...
    Mars飄殤閱讀 1,447評論 9 10
  • 目錄 Objective-C Runtime到底是什么 Objective-C的元素認(rèn)知 Runtime詳解 應(yīng)用...
    Ryan___閱讀 1,939評論 1 3
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 763評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理盹靴,服務(wù)發(fā)現(xiàn),斷路器瑞妇,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 原文出處:南峰子的技術(shù)博客 前面我們討論了Runtime中對類和對象的處理稿静,及對成員變量與屬性的處理。這一章辕狰,我們...
    _燴面_閱讀 245評論 0 0