Runtime(一)消息傳遞機制

Introduction

The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code.

OC是一種面向?qū)ο蟮膭討B(tài)語言知残,動態(tài)語言就是在運行時來執(zhí)行靜態(tài)語言的編譯鏈接的工作。這就要求除了編譯器之外還要有一種運行時系統(tǒng)來執(zhí)行編譯等功能粤蝎。OC中這個系統(tǒng)就是runtime赋除。

  • 編譯時間指編譯程序?qū)⒃闯绦蚓幾g成目標程序所占用的時間。
  • 源程序戳护,是指未經(jīng)編譯的金抡,按照一定的程序設(shè)計語言規(guī)范書寫的,人類可讀的文本文件腌且。通常由高級語言編寫梗肝。
  • 目標程序,又稱為“目的程序”铺董,為源程序經(jīng)編譯可直接被計算機運行的機器碼集合巫击,在計算機文件上以.obj作擴展名。目標代碼盡管已經(jīng)是機器指令,但是還不能運行喘鸟,因為目標程序還沒有解決函數(shù)調(diào)用問題匆绣,需要將各個目標程序與庫函數(shù)連接,才能形成完整的可執(zhí)行程序什黑。

Messaging

這一章描述了:

  • 消息表達式(message expression)如何轉(zhuǎn)換為objc_msgSend函數(shù)調(diào)用崎淳。
  • 如何通過名稱(name)來引用方法(methods)。
  • 說明如何充分利用objc_msgSend愕把。
  • 如何規(guī)避(circumvent)動態(tài)綁定(dynamic binding)拣凹。

The objc_msgSend Function

[receiver message]

在OC中,消息(message)在運行時(runtime)才被綁定到方法實現(xiàn)恨豁。編譯器(compiler)把消息轉(zhuǎn)換(convert to)為函數(shù)objc_msgSend的調(diào)用嚣镜。objc_msgSend將接收方(receiver)和消息中提到的方法的名稱(即selector)作為函數(shù)的兩個重要的參數(shù):

objc_msgSend(receiver, selector)

消息中所有參數(shù)(arguments)也會傳遞給objc_msgSend函數(shù):

objc_msgSend(receiver, selector, arg1, arg2, ...)

objc_msgSend為動態(tài)綁定執(zhí)行所需的一切。

  • 首先橘蜜,它查找selector引用的實現(xiàn)方法菊匿。(因為相同的方法可以被不同的類實現(xiàn),所以定位精確的實現(xiàn)方法取決于receiver的的類型)
  • 然后计福,調(diào)用實現(xiàn)方法跌捆,把receiver和方法指定的參數(shù)傳遞給它。
  • 最后象颖,把實現(xiàn)方法的返回值作為它的返回值佩厚。

note:編譯器生成對objc_msgSend的調(diào)用,你不要直接在代碼中直接調(diào)用它

消息傳遞的關(guān)鍵依賴于編譯器為每個類和對象創(chuàng)建的結(jié)構(gòu)(structures)说订,每個類結(jié)構(gòu)包含兩個基本(essential)元素:

  • 一個指向父類的指針(A point to the superclass)
  • 一個類的調(diào)度表(A class dispatch table)抄瓦。這個表擁有將方法選擇器(method selector)與特定類的方法地址相關(guān)聯(lián)的條目(entries)。例如:setOrigin::的selector與setOrigin::的實現(xiàn)方法(implementation)地址關(guān)聯(lián)起來陶冷。

當(dāng)創(chuàng)建一個新對象時钙姊,內(nèi)存會為它分配空間,并且它的實例變量會被初始化埃叭。這個對象的所有變量中第一個是isa指針(指向它的類structure)摸恍,object可以根據(jù)isa訪問它的類和父類。


當(dāng)一個objc_msgSend發(fā)送給一個對象時赤屋,沿著isa查找類結(jié)構(gòu)中調(diào)度表(dispatch table)中的selector對應(yīng)的實現(xiàn)方法的地址(address)。如果沒有找到對應(yīng)的selector壁袄,則繼續(xù)沿著isa查找父類的dispatch table的selector类早。連續(xù)的失敗(successive failures)導(dǎo)致objc_msgSend遍歷層級嗜逻,直到遍歷到NSObject涩僻。

為了加快消息傳遞速度,runtime系統(tǒng)會緩沖(cache)已經(jīng)使用過的selectors和addresses of methods。每一個類都單獨(seperate)創(chuàng)建cache緩沖繼承(inherited)的和定義的方法逆日。

Using Hidden Arguments

當(dāng)objc_msgSend找到方法實現(xiàn)的地址嵌巷,調(diào)用方法,并把message中的arguments傳遞給它室抽。同時搪哪,也包含兩個隱藏的(hidden)arguments。

  • 接受消息的對象(The receiving object)坪圾。
  • 方法的選擇器(The selector for the method)晓折。

這兩個參數(shù)為方法實現(xiàn)提供了明確的信息:消息表達式的兩半(即[receiver message])。方法將receiving object引用為self兽泄,將selector引用為_cmd漓概。

Getting a Method Address

void (*setter)(id, SEL, BOOL);
int i;
setter = (void(*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];
for (i = 0, i < 1000, i++) {
  setter(targetList(i), @selector(setFilled:), YES);
}

阻止動態(tài)綁定的唯一方式:獲取方法的地址(addresss),直接調(diào)用它(如果它是一個函數(shù))病梢。這種情況只適合在連續(xù)多次調(diào)用某個方法的時候胃珍,可以減少動態(tài)綁定的消耗。

NSObject的methodForSelector:返回一個方法(method)的指針(pointer)蜓陌,用這個pointer去實現(xiàn)一個方觅彰。methodForSelector:返回的指針必須小心的轉(zhuǎn)換為正確的函數(shù)類型。返回和參數(shù)類型都應(yīng)該包含在轉(zhuǎn)換中护奈。例如:

void (*setter)(id, SEL, BOOL);
int i;
setter = (void(*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];

接受對象(receiving object)和方法選擇器(method selecotr)缔莲,這兩個參數(shù)(arguments)在方法語法中(method syntax)中是被隱藏的,但是方法作為函數(shù)(function)調(diào)用時霉旗,必須是顯示的(explicit)痴奏。例如:

setter(targetList(i), @selector(setFilled:), YES);

使用methodForSelector:阻止動態(tài)綁定在消息傳遞中節(jié)省了大部分時間,但是這大部分時間只有在以下情況才有意義:某個確定的方法連續(xù)的調(diào)用厌秒。如在for loop读拆。

note:methodForSelector:由Cocoa runtime system提供,不是Objective-C語言的特定鸵闪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末檐晕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蚌讼,更是在濱河造成了極大的恐慌辟灰,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篡石,死亡現(xiàn)場離奇詭異芥喇,居然都是意外死亡,警方通過查閱死者的電腦和手機凰萨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門继控,熙熙樓的掌柜王于貴愁眉苦臉地迎上來械馆,“玉大人,你說我怎么就攤上這事武通∨椋” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵冶忱,是天一觀的道長尾菇。 經(jīng)常有香客問我,道長朗和,這世上最難降的妖魔是什么错沽? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮眶拉,結(jié)果婚禮上千埃,老公的妹妹穿的比我還像新娘。我一直安慰自己忆植,他們只是感情好放可,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朝刊,像睡著了一般耀里。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拾氓,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天冯挎,我揣著相機與錄音,去河邊找鬼咙鞍。 笑死房官,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的续滋。 我是一名探鬼主播翰守,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疲酌!你這毒婦竟也來了蜡峰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朗恳,失蹤者是張志新(化名)和其女友劉穎湿颅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粥诫,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡肖爵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了臀脏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劝堪。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖揉稚,靈堂內(nèi)的尸體忽然破棺而出秒啦,到底是詐尸還是另有隱情,我是刑警寧澤搀玖,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布余境,位于F島的核電站,受9級特大地震影響灌诅,放射性物質(zhì)發(fā)生泄漏芳来。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一猜拾、第九天 我趴在偏房一處隱蔽的房頂上張望即舌。 院中可真熱鬧,春花似錦挎袜、人聲如沸顽聂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽紊搪。三九已至,卻和暖如春全景,著一層夾襖步出監(jiān)牢的瞬間耀石,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工爸黄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留滞伟,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓馆纳,卻偏偏與公主長得像诗良,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鲁驶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉鉴裹,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,721評論 0 9
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,560評論 33 466
  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡介 Runt...
    樂樂的簡書閱讀 2,136評論 0 9
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 735評論 0 2
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 763評論 0 1