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

這是Effective Objective-C 2.0 的第12條

消息傳遞

我們先簡單講一下消息傳遞的過程。

當(dāng)我們向某個對象(接收者)傳遞一個消息,在運行時匆篓,會先去這個對象的所屬類中進行方法匹配揖赴,首先去cache列表中查找诡延,如果沒有,再去方法列表中查找忙菠,找到了調(diào)用何鸡,若找不到,則去父類方法列表中查找牛欢,一直向上找骡男,期間如果可以匹配成功,則調(diào)用方法傍睹,并將其緩存到對象所屬類的cache列表中隔盛,以方便下次查找犹菱,如果一直找不到,那就會進行“消息轉(zhuǎn)發(fā)”吮炕。那么消息轉(zhuǎn)發(fā)是如何進行的呢腊脱?

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

其實,在一開始龙亲,并不會去轉(zhuǎn)發(fā)陕凹,而是會進行一次詢問

“喂,小鬼鳄炉,再給你一次機會杜耙,要不要現(xiàn)在添加方法?”

“現(xiàn)在拂盯?運行時泥技?可以這么做么?”

當(dāng)讓可以磕仅,這就是OC語言的強大之處珊豹,可以動態(tài)添加方法。怎么做呢榕订?

首先店茶,我們先準備好一個函數(shù),這個函數(shù)就可以認為是給消息的一個實現(xiàn)劫恒。

接著在所屬類中實現(xiàn)這么一個方法

這個方法是干嘛的贩幻?這個方法其實就是對接受者所屬類的詢問,在其內(nèi)部通過class_addMethod這個函數(shù)两嘴,向當(dāng)前類提供消息的實現(xiàn)丛楚,這個函數(shù)的原型如下

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

OK,這樣我們就動態(tài)的添加了一個方法實現(xiàn)憔辫,運行成功趣些,cool!這邊我們要注意的是,如果接受是類贰您,會通過resolveClassMethod:方法進行訊問坏平。

倘若我們沒有實現(xiàn)這個方法,那會怎樣呢锦亦?

“小鬼舶替,那你看看有沒有人可以幫你做這個事情?”

“案茉啊顾瞪?找人幫忙啊!”

“有的話陈醒,我就把這個消息發(fā)給他惕橙。”

是的孵延,此時會再次訊問接受者,有沒有其他對象可以執(zhí)行這個操作亲配,若有尘应,則進行消息轉(zhuǎn)發(fā)。那如何訊問呢吼虎?是通過下面這個方法

- (id)forwardingTargetForSelector:(SEL)aSelector

我們需要返回一個對象犬钢,這個對象就是轉(zhuǎn)發(fā)后的消息接受者,如:

此時Animal對象就成為了消息接受者思灰。

好了玷犹,如果到了這一步還是沒有任何作為的話,就會進行最后一步了

“小鬼洒疚,給你最后一次幾回歹颓,我把所有消息相關(guān)的細節(jié)全部封裝在一個對象中,你去最后想辦法處理一下吧油湖?”

此時巍扛,運行時系統(tǒng)會將所有的細節(jié)(消息、目標)封裝一個NSInvocation對象中乏德,我們可以修改一些細節(jié)撤奸,是其做一些處理。比如我們依然可以在這個時候修改消息接收者喊括,類似于上面的操作

我們在此時調(diào)用來方法胧瓜,但改變了方法的執(zhí)行的目標。這個方法我們要注意一個細節(jié)郑什,要想改變目標執(zhí)行這個方法府喳,我們需要先注冊一下這個消息的類型

好了,基本整個消息轉(zhuǎn)發(fā)的流程就到此結(jié)束了蘑拯。對于forwardInvocation:這個方法劫拢,如果發(fā)現(xiàn)依然做不了事情,會去調(diào)用父類的此方法强胰,一直到NSObject,如果到了NSObject,該方法會調(diào)用doesNotRecognizedSelector:方法舱沧,拋出異常。

上面的這些方法偶洋,我們除了可以捕獲轉(zhuǎn)發(fā)流程熟吏,其實我們也可以利用著做一些其他的事情,比如說實現(xiàn)@dynamic屬性的方法,實現(xiàn)多重繼承等功能牵寺,這些有機會再聊悍引。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市帽氓,隨后出現(xiàn)的幾起案子趣斤,更是在濱河造成了極大的恐慌,老刑警劉巖黎休,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浓领,死亡現(xiàn)場離奇詭異,居然都是意外死亡势腮,警方通過查閱死者的電腦和手機联贩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捎拯,“玉大人泪幌,你說我怎么就攤上這事∈鹫眨” “怎么了祸泪?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長建芙。 經(jīng)常有香客問我浴滴,道長,這世上最難降的妖魔是什么岁钓? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任升略,我火速辦了婚禮,結(jié)果婚禮上屡限,老公的妹妹穿的比我還像新娘品嚣。我一直安慰自己,他們只是感情好钧大,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布翰撑。 她就那樣靜靜地躺著,像睡著了一般啊央。 火紅的嫁衣襯著肌膚如雪眶诈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天瓜饥,我揣著相機與錄音逝撬,去河邊找鬼。 笑死乓土,一個胖子當(dāng)著我的面吹牛宪潮,可吹牛的內(nèi)容都是我干的溯警。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼狡相,長吁一口氣:“原來是場噩夢啊……” “哼梯轻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尽棕,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤喳挑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滔悉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伊诵,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年氧敢,在試婚紗的時候發(fā)現(xiàn)自己被綠了日戈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片询张。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡孙乖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出份氧,到底是詐尸還是另有隱情唯袄,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布蜗帜,位于F島的核電站恋拷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏厅缺。R本人自食惡果不足惜蔬顾,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望湘捎。 院中可真熱鬧诀豁,春花似錦、人聲如沸窥妇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽活翩。三九已至烹骨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間材泄,已是汗流浹背沮焕。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拉宗,地道東北人遇汞。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親空入。 傳聞我的和親對象是個殘疾皇子络它,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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