[iOS] ios的runtime

wangcuoer發表於2016-03-21

1. 什麼是runtime

執行時刻是指一個程式在執行(或者在被執行)的狀態。也就是說,當你開啟一個程式使它在電腦上執行的時候,那個程式就是處於執行時刻。在一些程式語言中,把某些可以重用的程式或者例項打包或者重建成為"執行庫"。這些例項可以在它們執行的時候被連線或者被任何程式呼叫。
程式設計師有時候會在什麼東西應該在編譯的時候載入進來以及什麼東西該在執行的時候使用之間做出抉擇,前者有時候成為編譯時期。
一段時間以來,技術類作者都拒絕使用"執行時刻"作為一種術語,他們堅持類似於"一個程式在執行"之類的說法,用以避免需要一個專門的術語。後來,這個術語逐漸地蔓延到通常的應用中。

Runtime類封裝了執行時的環境。每個 Java 應用程式都有一個 Runtime 類例項,使應用程式能夠與其執行的環境相連線。
一般不能例項化一個Runtime物件,應用程式也不能建立自己的 Runtime 類例項,但可以通過 getRuntime 方法獲取當前Runtime執行時物件的引用。
一旦得到了一個當前的Runtime物件的引用,就可以呼叫Runtime物件的方法去控制Java虛擬機器的狀態和行為。
當Applet和其他不被信任的程式碼呼叫任何Runtime方法時,常常會引起SecurityException異常。

以上內容來自百度百科

 

runtime
In computer science,run time, run-time, runtime, or execution timeis the time during which a program is running (executing), in contrast to other phases of a program's lifecycle such ascompile time,link time,load time, etc.
Arun-time erroris detected after or during the execution of a program, whereas a compile-time error is detected by the compiler before the program is ever executed.Type checking, storage allocation, code generation, and code optimization are typically done at compile time, but may be done at run time depending on the particular language and compiler.


In most cases, the execution of a program begins after a loader performed the necessary memory setup and linked the program with any dynamically linked libraries it needs.In some cases a language or implementation will have these tasks done by the language runtime instead, though this is unusual in mainstream languages on common consumer operating systems.
Some program debugging can only be performed (or are more efficient or accurate) when performed at runtime. Logical errors and array bounds checking are examples. For this reason, some programming bugs are not discovered until the program is tested in a "live" environment with real data, despite sophisticated compile-time checking and pre-release testing. In this case, the end user may encounter aruntime errormessage.

 

Exception handling is one language feature designed to handle runtime errors, providing a structured way to catch completely unexpected situations as well as predictable errors or unusual results without the amount of inline error checking required of languages without it.More recent advancements in runtime engines enable automated exception handling which provides 'root-cause' debug information for every exception of interest and is implemented independent of the source code, by attaching a special software product to the runtime engine.

 

runtime library

In computer programming, a runtime library is a special program library used by a compiler, to implement functions built into a programming language, during the execution (runtime) of a computer program.This often includes functions for input and output, or for memory management.
When the source code of a computer program is translated into the respective target language by a compiler, it would cause an extreme enlargement of program code if each command in the program and every call to a built-in function would cause the in-place generation of the complete respective program code in the target language every time. Instead the compiler often uses compiler-specific auxiliary functions in the runtime library that are mostly not accessible to application programmers. Depending on the compiler manufacturer, the runtime library will sometimes also contain the standard library of the respective compiler or be contained in it.
Also some functions that can be performed only (or are more efficient or accurate) at runtime are implemented in the runtime library, e.g. some logic errors, array bounds checking, dynamic type checking, exception handling and possibly debugging functionality.For this reason, some programming bugs are not discovered until the program is tested in a "live" environment with real data, despite sophisticated compile-time checking and pre-release testing. In this case, the end user may encounter a runtime error message.
Usually the runtime library realizes many functions by accessing the operating system. Many programming languages have built-in functions that do not necessarily have to be realized in the compiler, but can be implemented in the runtime library. So the border between runtime library and standard library is up to the compiler manufacturer. Therefore a runtime library is always compiler-specific and platform-specific.
The concept of a runtime library should not be confused with an ordinary program library like that created by an application programmer or delivered by a third party or a dynamic library, meaning a program library linked at run time. For example, the programming language C requires only a minimal runtime library, but defines a large standard library (called C standard library) that each implementation has to deliver.

以上內容來自維基百科

 

2. OC的runtime

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的靈魂。很多東西都是在這個基礎上出現的。所以它是指的你花功夫去理解的。

0

相關文章