Objective-C消息機(jī)制的原理

在Objective-C中蒙秒,message與方法的真正實(shí)現(xiàn)是在執(zhí)行階段綁定的苔埋,而非編譯階段贱迟。編譯器會(huì)將消息發(fā)送轉(zhuǎn)換成對(duì)objc_msgSend方法的調(diào)用塞关。

objc_msgSend方法含兩個(gè)必要參數(shù):receiver抬探、方法名(即:selector),如:

[receiver message];將被轉(zhuǎn)換為:objc_msgSend(receiver, selector);

objc_msgSend方法也能hold住message的參數(shù),如:

objc_msgSend(receiver, selector, arg1, arg2, …);

objc_msgSend方法會(huì)做按照順序進(jìn)行以下操作小压,以完成動(dòng)態(tài)綁定:

查找selector所指代的程序(方法的真正實(shí)現(xiàn))线梗。因?yàn)椴煌?lèi)對(duì)同一方法有不同的實(shí)現(xiàn),所以對(duì)方法的真正實(shí)現(xiàn)的查找依賴(lài)于receiver的類(lèi)

調(diào)用該實(shí)現(xiàn)怠益,并將一系列參數(shù)傳遞過(guò)去

將該實(shí)現(xiàn)的返回值作為自己的返回值仪搔,返回之

消息傳遞的關(guān)鍵是,編譯器構(gòu)建每個(gè)類(lèi)和對(duì)象時(shí)所采用的數(shù)據(jù)結(jié)構(gòu)蜻牢。每個(gè)類(lèi)都包含以下兩個(gè)必要元素:

一個(gè)指向父類(lèi)的指針

一個(gè)調(diào)度表(dispatch table)烤咧。該調(diào)度表將類(lèi)的selector與方法的實(shí)際內(nèi)存地址關(guān)聯(lián)起來(lái)

每個(gè)對(duì)象都有一個(gè)指向所屬類(lèi)的指針isa。通過(guò)該指針抢呆,對(duì)象可以找到它所屬的類(lèi)煮嫌,也就找到了其全部父類(lèi),如下圖所示:

當(dāng)向一個(gè)對(duì)象發(fā)送消息時(shí)抱虐,objc_msgSend方法根據(jù)對(duì)象的isa指針找到對(duì)象的類(lèi)昌阿,然后在類(lèi)的調(diào)度表(dispatch table)中查找selector。如果無(wú)法找到selector恳邀,objc_msgSend通過(guò)指向父類(lèi)的指針找到父類(lèi)懦冰,并在父類(lèi)的調(diào)度表(dispatch table)中查找selector,以此類(lèi)推直到NSObject類(lèi)谣沸。一旦查找到selector刷钢,objc_msgSend方法根據(jù)調(diào)度表的內(nèi)存地址調(diào)用該實(shí)現(xiàn)。通過(guò)這種方式鳄抒,message與方法的真正實(shí)現(xiàn)在執(zhí)行階段才綁定闯捎。

為了保證消息發(fā)送與執(zhí)行的效率,系統(tǒng)會(huì)將全部selector和使用過(guò)的方法的內(nèi)存地址緩存起來(lái)许溅。每個(gè)類(lèi)都有一個(gè)獨(dú)立的緩存瓤鼻,緩存包含有當(dāng)前類(lèi)自己的selector以及繼承自父類(lèi)的selector。查找調(diào)度表(dispatch table)前贤重,消息發(fā)送系統(tǒng)首先檢查receiver對(duì)象的緩存茬祷。

緩存命中的情況下,消息發(fā)送(messaging)比直接調(diào)用方法(function call)只慢一點(diǎn)點(diǎn)點(diǎn)點(diǎn)并蝗。

參考資料:

Objective-C Runtime Programming Guide

The Objective-C Programming Language

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祭犯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滚停,更是在濱河造成了極大的恐慌沃粗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件键畴,死亡現(xiàn)場(chǎng)離奇詭異侨嘀,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)碧库,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)咏删,“玉大人,你說(shuō)我怎么就攤上這事问词《胶” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵激挪,是天一觀的道長(zhǎng)辰狡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)垄分,這世上最難降的妖魔是什么搓译? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮锋喜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘豌鸡。我一直安慰自己嘿般,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布涯冠。 她就那樣靜靜地躺著炉奴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蛇更。 梳的紋絲不亂的頭發(fā)上瞻赶,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音派任,去河邊找鬼砸逊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛掌逛,可吹牛的內(nèi)容都是我干的师逸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼豆混,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼篓像!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起皿伺,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤员辩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鸵鸥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奠滑,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了养叛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片种呐。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弃甥,靈堂內(nèi)的尸體忽然破棺而出爽室,到底是詐尸還是另有隱情,我是刑警寧澤淆攻,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布阔墩,位于F島的核電站,受9級(jí)特大地震影響瓶珊,放射性物質(zhì)發(fā)生泄漏啸箫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一伞芹、第九天 我趴在偏房一處隱蔽的房頂上張望忘苛。 院中可真熱鬧,春花似錦唱较、人聲如沸扎唾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胸遇。三九已至,卻和暖如春汉形,著一層夾襖步出監(jiān)牢的瞬間纸镊,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工概疆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逗威,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓届案,卻偏偏與公主長(zhǎng)得像庵楷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子楣颠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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