官方文檔:
objective - c語言盡可能決定許多推遲時間運行時編譯時間和鏈接。只要有可能,它動態(tài)做凡纳。這意味著語言需要的不僅僅是一個編譯器,但也一個運行時系統(tǒng)來執(zhí)行編譯后的代碼余寥。運行時系統(tǒng)作為一種操作系統(tǒng)的objective - c語言;以便使這門語言運行起來领铐。本文著眼于NSObject類和objective - c程序如何與運行時系統(tǒng)交互。特別是,它檢查在運行時動態(tài)加載新類的范例,并將消息轉(zhuǎn)發(fā)給其他對象宋舷。當(dāng)您的程序正在運行绪撵,它還提供了關(guān)于如何找到信息對象的信息。你應(yīng)該閱讀本文檔了解objective - c運行時系統(tǒng)是如何工作的,以及如何利用它祝蝠。一般來說,你應(yīng)該沒有理由需要知道音诈。
有兩個版本的objective - c運行時——“現(xiàn)代”和“傳統(tǒng)”。介紹了現(xiàn)代版和objective - c 2.0包含一個新特性绎狭。遺留的編程接口版本的運行時在objective - c中描述1運行時參考;
現(xiàn)代版的運行時的編程接口描述在objective - c運行時參考细溅。最值得注意的新特性在現(xiàn)代運行時實例變量是“非脆弱”:
傳統(tǒng)的運行時,如果你改變布局一個類的實例變量,您必須重新編譯類繼承它。在現(xiàn)代運行時,如果你改變的布局實例變量在一個類中,您不必重新編譯類繼承它儡嘶。此外,現(xiàn)代運行時支持聲明實例變量合成屬性(參見宣布屬性在objective - c編程語言)喇聊。
objective - c程序與運行時交互系統(tǒng)在三個不同的層次:通過objective - c源代碼;通過NSObject類中定義的方法的基礎(chǔ)框架;并通過直接調(diào)用運行時功能。
objective - c源代碼:
在大多數(shù)情況下,運行時系統(tǒng)自動和幕后工作蹦狂。你使用它只是通過編寫和編譯objective - c源代碼誓篱。當(dāng)你編譯代碼包含objective - c的類和方法,編譯器創(chuàng)建數(shù)據(jù)結(jié)構(gòu)和函數(shù)調(diào)用,實現(xiàn)語言的動態(tài)特性。數(shù)據(jù)結(jié)構(gòu)中捕捉信息類和類定義和在協(xié)議聲明,其中包括討論的對象類和協(xié)議在objective - c中定義一個類和協(xié)議編程語言,以及選擇器方法,實例變量模板凯楔、凈化從源代碼和其他信息窜骄。主要運行時函數(shù)是發(fā)送消息,所述消息傳遞。它調(diào)用的源代碼消息表達(dá)式摆屯。
runtime作用:
運行時系統(tǒng)是一個動態(tài)共享庫和一個公共接口組成的一組函數(shù)和數(shù)據(jù)結(jié)構(gòu)在頭文件位于/usr/include/objc.的目錄邻遏,當(dāng)你寫代碼時這些函數(shù)允許您使用純C復(fù)制objective - C編譯器做什么。其他形式的基礎(chǔ)功能導(dǎo)出NSObject類的方法鸥拧。這些功能可以開發(fā)其他接口運行時系統(tǒng)和生產(chǎn)工具,增加開發(fā)環(huán)境;他們不需要在objective - c編程党远。然而,一些運行時功能有時可能編寫一個objective - c程序時有用削解。所有這些功能都是記錄在objective - c運行時參考富弦。
消息傳遞(message)
這一章描述了消息表達(dá)式轉(zhuǎn)換成objc_msgSend函數(shù)調(diào)用,以及你如何可以參考方法的名字。然后解釋如何利用objc_msgSend,,如果你需要氛驮,你可以繞過動態(tài)綁定腕柜。
objc_msgSend(receiver, selector, arg1, arg2, ...)
消息傳遞函數(shù)是動態(tài)綁定所需的一切:
它首先發(fā)現(xiàn)的過程(方法實現(xiàn))選擇器。因為相同的方法可以實現(xiàn)不同的單獨的類,精確的過程,它查找取決于接收器的類。
然后調(diào)用程序,通過它接收對象(一個指向它的數(shù)據(jù)),以及任何指定的參數(shù)的方法盏缤。最后,它的返回值傳遞過程的返回值砰蠢。
注:編譯器生成調(diào)用消息傳遞功能。你不應(yīng)該直接調(diào)用在您編寫的代碼唉铜。
消息傳遞的關(guān)鍵在于編譯器為每個類和對象構(gòu)建的結(jié)構(gòu)台舱。每個類結(jié)構(gòu)包括兩個基本要素:
一個指向超類。
一個類分派表潭流。這個表,指向?qū)S玫刂返姆椒ㄟx擇器所識別的方法竞惋。setOrigin的選擇器:與地址相關(guān)聯(lián)的方法(程序?qū)崿F(xiàn))setOrigin::,選擇器顯示方法與地址,等等。創(chuàng)建一個新對象時,內(nèi)存分配,和它的實例變量初始化灰嫉。首先在對象的變量是一個指針指向它的類結(jié)構(gòu)拆宛。這個指針,稱為isa,給出了類和對象訪問,通過類的所有類繼承。
當(dāng)一個消息發(fā)送到一個對象,消息傳遞函數(shù)是對象的isa指針的類結(jié)構(gòu)看起來方法分派表中選擇器讼撒。如果找不到選擇器,objc_msgSend遵循指向父類的指針,并試圖找到分派表的選擇器浑厚。連續(xù)失敗導(dǎo)致objc_msgSend攀爬類的層次結(jié)構(gòu),直到它到達(dá)NSObject類。一旦定位選擇器,表中輸入的函數(shù)調(diào)用方法并將其傳遞接收對象的數(shù)據(jù)結(jié)構(gòu)根盒。選擇這個方式方法實現(xiàn)在運行時,在面向?qū)ο缶幊痰男性?方法是動態(tài)綁定到消息钳幅。加速消息傳遞過程中,運行時系統(tǒng)使用緩存選擇器和地址的方法。有一個為每個類單獨的緩存,它可以包含繼承的方法以及方法的選擇器中定義的類炎滞。之前搜索調(diào)度表,收到的消息傳遞程序首先檢查緩存對象的類(在理論,一種方法是使用一次可能會再次使用)贡这。如果選擇器的方法是在緩存中,消息傳遞是僅略低于一個函數(shù)調(diào)用。一旦一個程序被運行足夠長的時間來“熱身”其緩存,幾乎所有它發(fā)送的消息找到緩存的方法厂榛。緩存生長在程序運行時動態(tài)地適應(yīng)新的消息盖矫。
當(dāng)objc_msgSend發(fā)現(xiàn)程序?qū)崿F(xiàn)方法,它調(diào)用過程中所有的參數(shù)并將其傳遞消息。它還通過過程兩個隱藏的參數(shù):
The receiving object
The selector for the method