原帖位址:http://blog.csdn.net/wzzvictory/article/details/8615569
作為一門動态程式設計語言,Objective-C 會盡可能的将編譯和連結時要做的事情推遲到運作時。隻要有可能,Objective-C 總是使用動态 的方式來解決問題。這意味着 Objective-C 語言不僅需要一個編譯環境,同時也需要一個運作時系統來執行編譯好的代碼。運作時系統(runtime)扮演的角色類似于 Objective-C 語言的作業系統,Objective-C 基于該系統來工作。是以,runtime好比Objective-C的靈魂,很多東西都是在這個基礎上出現的。是以它是值的你花功夫去了解的。
我們将從以下幾個方面了解Objective-C的運作時:
一、與靜态語言編譯後的差別
1、靜态語言
一個靜态語言程式,如下所示的C程式:
[cpp] view plain copy
- #include < stdio.h >
- int main(int argc, const char **argv[])
- {
- printf("Hello World!");
- return 0;
- }
會經過編譯器的文法分析,優化然後将你最佳化的代碼翻譯成彙編語言,然後完全按照你設計的邏輯和你的代碼自上而下的執行。
2、Objective-C
很常見的一個消息發送語句:
[cpp] view plain copy
- [receiver message]
會被編譯器轉化成
[cpp] view plain copy
- objc_msgSend(receiver, selector)
如果有參數則為
[cpp] view plain copy
- objc_msgSend(receiver, selector, arg1, arg2, …)
消息隻有到運作時才會和函數實作綁定起來,而不是按照編譯好的邏輯一成不變的執行。 按照我的了解,編譯階段隻是确定了要去向receiver對象發送message消息,但是卻沒有發送,真正發送是等到運作的時候進行。是以,編譯階段完全不知道message方法的具體實作,甚至,該方法到底有沒有被實作也不知道。 這就有可能導緻運作時崩潰問題。
二、Objective-c runtime的幾點說明
1、runtime是開源的
是的,你沒看錯,runtime确實是開源的。目前蘋果公司和GNU各自維護一個開源的runtime版本,這兩個版本之間都在努力的保持一緻。其中蘋果的版本可以猛擊該連結下載下傳objc4-437.1.tar.gz
2、runtime是由C語言實作的
runtime做為Objective-C最核心的部分,幾乎全部由C語言實作。這裡的“幾乎”所指的例外就包含有的方法(比如下面要說道的objc_msgSend方法)甚至是用彙編實作的!!
3、runtime的兩個版本
Objective-C運作時系統有兩個已知版本:早期版本(Legacy)和現行版本(Modern)。
在現行版本中,最顯著的新特性就是執行個體變量是"健壯“(non-fragile)的:
在早期版本中,如果您改變類中執行個體變量的布局,您必須重新編譯該類的所有子類。
在現行版本中,如果您改變類中執行個體變量的布局,您無需重新編譯該類的任何子類。
此外,現行版本支援聲明property的synthesis屬性器。
目前iPhone 程式和 Mac OS X v10.5 及以後的系統中的 64 位程式使用的都是 Objective-C 運作時系統的現行版 本。其它情況(Mac OS X 系統中的 32 位程式)使用的是早期版本。
三、和runtime system互動的三種方式
1、通過Objective-C源代碼
大部分情況下,運作時系統在背景自動運作,我們隻需編寫和編譯 Objective-C 源代碼。
當編譯Objective-C類和方法時,編譯器為實作語言動态特性将自動建立一些資料結構和函數。這些資料 結構包含類定義和協定類定義中的資訊,如在Objective-C 2.0 程式設計語言中定義類和協定類一節所讨論 的類的對象和協定類的對象,方法選标,執行個體變量模闆,以及其它來自于源代碼的資訊。運作時系統的主要功能就是根據源代碼中的表達式發送消息。
2、通過類NSObject的方法
Cocoa程式中絕大部分類都是NSObject類的子類,是以大部分都繼承了NSObject類的方法,因而繼承 了NSObject的行為(NSProxy類是個例外)。然而,某些情況下, NSObject類僅僅定義了完成某件事情的模闆,而沒有提供所有需要的代碼。
例如,NSObject 類定義了description方法,傳回該類内容的字元串表示。這主要是用來調試程式 ——GDB 中的 print-object 方法就是直接列印出該方法傳回的字元串。NSObject 類中該方法的 實作并不知道子類中的内容,是以它隻是傳回類的名字和對象的位址。NSObject 的子類可以重新實作該方法以提供更多的資訊。例如,NSArray 類改寫了該方法來傳回 NSArray 類包含的每個對象的内容。
某些 NSObject 的方法隻是簡單地從運作時系統中獲得資訊,進而允許對象進行一定程度的自我檢查。
例如,class 傳回對象的類;isKindOfClass:和 isMemberOfClass:則檢查對象是否在指定的 類繼承體系中;respondsToSelector:檢查對象能否響應指定的消息;conformsToProtocol: 檢查對象是否實作了指定協定類的方法;methodForSelector:則傳回指定方法實作的位址。
3、通過運作時系統的函數
運作時系統是一個有公開接口的動态庫,由一些資料結構和函數的集合組成,這些資料結構和函數的聲明 頭檔案在/usr/include/objc中。這些函數支援用純C的函數來實作和Objective-C同樣的功能。還有一些函數構成了 NSObject 類方法的基礎。這些函數使得通路運作時系統接口和提供開發工具成為可 能。盡管大部分情況下它們在 Objective-C 程式不是必須的,但是有時候對于 Objecitve-C 程式來說某些函 數是非常有用的。 這些函數的文檔參見 Objective-C 2.0 運作時系統參考庫。
-------------未完待續-------------