runtime:消息傳遞過程解析

今天遇到了一個引人第三方崩潰的問題,崩潰的信息是-[NSURLResponse statusCode]: unrecognized selector sent to instance 0x15785f230',趁機學習一下runtime的消息傳遞機制硼端。我把每次防止崩潰的時刻成為轉機~影暴,宗旨就是根據SEL找到IMP(讓方法找到實現(xiàn))。

根據obj_msgSend方法的調用順序曹鸠,做了如下的嘗試:
1.首先寫了一個NSURLResponse的category造成,因為NSURLResponse是個系統(tǒng)的類搞旭,無法在.m文件修改內容:

在runtime時趁餐,沒有找到SEL的IML時會執(zhí)行resolveInstanceMethod喷兼。利用class_addMethod添加函數(shù)

在這次轉機中,還是很好理解的后雷,特別需要注意的是resolveInstanceMethod中包含的IMP季惯,實現(xiàn)方法是個C語言函數(shù)吠各,該函數(shù)中必須包含有id和SEL兩個參數(shù)。

2.如果resolveInstanceMethod返回的是NO星瘾,便會拐個彎繼續(xù)根據SEL去找IMP走孽。根據函數(shù)的名字forwardingTarget惧辈。琳状。就是改變target。盒齿。改變目標念逞。。

forwardingTargetForSelector返回的是一個其他對象边翁。

在這次轉機中翎承,看來這個類已經對自己失望了,所以要去尋找別的類對象是否有對應的函數(shù)實現(xiàn)符匾。

2'' 在下面的例子中叨咖,我嘗試在forwardingTargetForSelector中返回是對象本身,在對象內部寫了個函數(shù)啊胶,就好像對象自己回心轉意了一下~~甸各,還是可以執(zhí)行的。我就暫且把它稱為回旋轉機吧焰坪。這樣做其實是不和常規(guī)的趣倾,完全可以在第一次轉機的時候。這里只是做個測試~

forwardingTargetForSelector返回的依然是其自身

3.methodSignatureForSelector應該是讓對象最桑心的選擇了某饰,連其他對象都沒有想要的函數(shù)儒恋,只能把函數(shù)的簽名扔到茫茫人海中了。黔漂。就是將函數(shù)名稱包裝成簽名NSMethodSignature诫尽。方法簽名僅包含了參數(shù)類型和返回值。所以人家還需要調用forwardInvocation的調用才行炬守。

methodSignatureForSeletor和forwardInvocation配合使用

在這次轉機中牧嫉,forwardInvocation函數(shù)內部,可以有很豐富的封裝劳较【灾梗可以拿到函數(shù)名,獲取參數(shù)观蜗,設置返回值等臊恋。


另一方對象的實現(xiàn)

以上所寫的內容,是為了屏蔽掉崩潰的問題墓捻。那么在平時的使用中抖仅,如果是想動態(tài)實現(xiàn)函數(shù)坊夫,還需要重載respondsToSelector中,將想要動態(tài)實現(xiàn)的函數(shù)返回為yes撤卢。不然調用respondeToSelector時环凿,會返回NO。

objc_msgSend的調用過程如下:

0.檢測這個selector是不是要忽略的放吩。()

1.首先檢測消息的接受者是否為nil智听,如果是nil,就不再發(fā)送消息了渡紫,所以nil對象執(zhí)行任何一個操作都不會崩潰到推。(插曲:曾經想要寫一個字符串的擴展,如果對象是nil惕澎,就輸出孔字符串@“”莉测。但是怎么也不生效。最后才恍然大悟唧喉,對象是nil捣卤,連消息都接收不到,怎么可能還變成@“”“诵ⅲ現(xiàn)在想想也是蠻有趣的董朝。)
///////////////////////////////////////////////////////////////////////////////////
如果是實例方法:
2.檢查class的緩存中是否有這個方法的實現(xiàn)。如果有唆阿,就調用益涧。(struct objc_cache *cache)指向最近使用的方法的指針,提高效率
3.若找不到驯鳖,就查找方法列表闲询。(struct objc_method_list **methodLists)方法地址列表,如CLS_CLASS (0x1L)浅辙,則存儲實例方法扭弧,如CLS_META (0x2L),則存儲類方法;
4.查看父類中的methodLists是否有該方法的實現(xiàn)记舆,如果沒有就再查找父類的父類中是否有該方法鸽捻。知道NSObject的根類為止。
///////////////////////////////////////////////////////////////////////////////////
如果是類方法:
2.會通過自己的isa找到自身類的metaClass(metaClass是用來存放類本身的泽腮,類方法就存儲在metaclass中的methodList中)御蒲,在methodList中查找
3.若找不到,就去查找metaClass的superClass诊赊,查找他的superClass(也是metaClass)的methodList中是否有對應函數(shù)厚满。
////////////////////////////////////////////////////////////////////////////////////

5.調用resolveInstanceMethod:(或者resolveClassMethod:)如果有,就返回yes碧磅。并調用
6.調用forwardingTargetForSelector函數(shù)碘箍,如果返回的對象中包含該方法遵馆,調用
7.調用methodSignatureForSelector函數(shù),如果返回了一個函數(shù)的簽名丰榴,再調用forwardInvocation货邓。根據里面的函數(shù),調用即可四濒。
8.調用doesNotRecognizeSelector换况。拋出異常

注意metaclass的isa直接就是metaclass的rootclass了。



消息傳遞機制

參考文章:

http://www.cnblogs.com/biosli/p/NSObject_inherit_2.html

http://my.oschina.net/u/566401/blog/182520

http://www.henishuo.com/runtime-message-forwarding/

http://blog.sunnyxx.com/2014/11/06/runtime-nuts/

最后峻黍,推薦一個我自己的產品复隆,找到我啦,可查看軌跡和定位姆涩,歡迎關注我的微信公眾號,時刻關注找到我啦的更新


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末惭每,一起剝皮案震驚了整個濱河市骨饿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌台腥,老刑警劉巖宏赘,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異黎侈,居然都是意外死亡察署,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門峻汉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贴汪,“玉大人,你說我怎么就攤上這事休吠“夤。” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵瘤礁,是天一觀的道長阳懂。 經常有香客問我,道長柜思,這世上最難降的妖魔是什么岩调? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮赡盘,結果婚禮上号枕,老公的妹妹穿的比我還像新娘。我一直安慰自己亡脑,他們只是感情好堕澄,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布邀跃。 她就那樣靜靜地躺著,像睡著了一般蛙紫。 火紅的嫁衣襯著肌膚如雪拍屑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天坑傅,我揣著相機與錄音僵驰,去河邊找鬼。 笑死唁毒,一個胖子當著我的面吹牛蒜茴,可吹牛的內容都是我干的。 我是一名探鬼主播浆西,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粉私,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了近零?” 一聲冷哼從身側響起诺核,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎久信,沒想到半個月后窖杀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡裙士,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年入客,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腿椎。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡桌硫,死狀恐怖,靈堂內的尸體忽然破棺而出酥诽,到底是詐尸還是另有隱情鞍泉,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布肮帐,位于F島的核電站咖驮,受9級特大地震影響,放射性物質發(fā)生泄漏训枢。R本人自食惡果不足惜托修,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恒界。 院中可真熱鬧睦刃,春花似錦、人聲如沸十酣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兴泥,卻和暖如春工育,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搓彻。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工如绸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旭贬。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓怔接,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稀轨。 傳聞我的和親對象是個殘疾皇子扼脐,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容

  • 轉至元數(shù)據結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數(shù)據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評論 0 9
  • 前言 runtime其實在我們日常開發(fā)過程中很少使用到靶端,尤其是像我現(xiàn)在比較初級的程序猿就更用不到了谎势。但是去面試很多...
    WolfTin閱讀 622評論 0 2
  • 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,554評論 33 466
  • 一、Runtime簡介 Runtime簡稱運行時杨名。OC就是運行時機制,也就是在運行時候的一些機制猖毫,其中最主要的是消...
    林安530閱讀 1,064評論 0 2
  • 運行時是iOS中一個很重要的概念台谍,iOS運行過程中都會被轉化為runtime的C代碼執(zhí)行。例如[target do...
    蘿卜醬紫閱讀 396評論 0 3