ios runtime environment

Objective-c是動態語言,  很多新手或者開發人員常常被Runtime這個東西所迷惑。而恰恰這是一個非常重要的概念。 爲什麼重要呢!?我可以這麼問:“如果讓你(設計、)實現一個計算機語言,你要如何下手?” 很少程序員這麼思考過。但是這麼一問,就會強迫你從更高層次思考(1)以前的問題了。 注意我這句話‘設計’括起來了,稍微次要點,關鍵是實現。

我把實現分成3鐘不同的層次:
1. 傳統的面向過程的語言開發,例如c語言。實現c語言編譯器很簡單,只要按照語法規則實現一個LALR語法分析器就可以了,編譯器優化是非常難的topic,不在這裏討論範圍內,忽略。 這裏我們實現了編譯器其中最最基礎和原始的目標之一就是把一份代碼裏的函數名稱,轉化成一個相對內存地址,把調用這個函數的語句轉換成一個jmp跳轉指令。在程序開始運行時候,調用語句可以正確跳轉到對應的函數地址。 這樣很好,也很直白,但是。。。太死板了。everything is per-determined

2. 我們希望靈活,於是需要開發面向對象的語言,例如c++。 c++在c的基礎上增加了類的部分。但這到底意味着什麼呢?我們在寫它的編譯器要如何考慮呢?其實,就是讓編譯器多繞個彎,在嚴格的c編譯器上增加一層類處理的機制,把一個函數限制在它處在的class環境裏,每次請求一個函數調用,先找到它的對象, 其類型,返回值,參數等等,確定了這些後再jmp跳轉到需要的函數。這樣很多程序增加了靈活性同樣一個函數調用會根據請求參數和類的環境返回完全不同的結果。增加類機制後,就模擬了現實世界的抽象模式,不同的對象有不同的屬性和方法。同樣的方法,不同的類有不同的行爲! 這裏大家就可以看到作爲一個編譯器開發者都做了哪些進一步的思考。但是。。。還是死板, 我們仍然叫c++是static language。

3. 希望更加靈活! 於是我們完全把上面哪個類的實現部分抽象出來,做成一套完整運行階段的檢測環境。這次再寫編譯器甚至保留部分代碼裏的sytax名稱,名稱錯誤檢測,runtime環境註冊所有全局的類,函數,變量等等信息等等,我們可以無限的爲這個層增加必要的功能。調用函數時候,會先從這個運行時環境裏檢測所以可能的參數再做jmp跳轉,這就是runtime。編譯器開發起來比上面更加彎彎繞。但是這個層極大增加了程序的靈活性。  例如當調用一個函數時候,前2種語言,很有可能一個jmp到了一個非法地址導致程序crash, 但是在這個層次裏面,runtime就過濾掉了這些可能性。 這就是爲什麼dynamic langauge更加強壯。 因爲編譯器和runtime環境開發人員已經幫你處理了這些問題。

好了上面說着這麼多,我們再返回來看objective-c.  現在你是不是能理解這樣的語句了呢?
    id obj=self;
    if ([obj respondsToSelector:@selector(function1:)) {
    }
    if ([obj isKindOfClass:[NSArray class]] ) {
    }
    if ([obj conformsToProtocol:@protocol(myProtocol)]) {
    }           
    if ([[obj class] isSubclassOfClass:[NSArray class]]) {
    }
    [obj someNonExistFunction];


看似很簡單的語句,但是爲了讓語言實現這個能力,語言開發者要付出很多努力實現runtime環境。這裏運行時環境處理了弱類型函數存在檢查工作。runtime會檢測註冊列表裏是否存在對應的函數,類型是否正確,最後確定下來正確的函數地址,再進行保存寄存器狀態,壓棧,函數調用等等實際的操作。

    id knife=[Knife grateKnife];
    NSArray *monsterList=[NSArray array];
    [monsterList makeObjectsPerformSelector:@selector(killMonster:) withObject:knife];

在c,c++年代去完成這個功能是非常麻煩的,但是動態語言卻非常簡單。

關於執行效率問題。 “靜態語言執行效率要比動態語言高”,這句沒錯。因爲一部分cpu計算損耗在了runtime過程中。而靜態語言生成的機器指令更簡潔。正因爲知道這個原因,所以開發語言的人付出很大一部分努力爲了保持runtime小巧上。所以objecitve-c是c的超集+一個小巧的runtime環境。  但是,換句話說,從算法角度考慮,這點複雜度不算差別的,Big O notation結果不會有差別。( It's not log(n) vs n^2 )

簡單理解:“Runtime is everything between your each function call.” 
Runtime好比objective-c的靈魂。很多東西都是在這個基礎上出現的。所以它是指的你花功夫去理解的。



http://hi.baidu.com/marktian/item/831e1de5d295a80b8d3ea8f4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章