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是动态语言,
我把实现分成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。编译器开发起来比上面更加弯弯绕。但是这个层极大增加了程序的灵活性。
好了上面说着这么多,我们再返回来看objective-c.
看似很简单的语句,但是为了让语言实现这个能力,语言开发者要付出很多努力实现runtime环境。这里运行时环境处理了弱类型、函数存在检查工作。runtime会检测注册列表里是否存在对应的函数,类型是否正确,最后确定下来正确的函数地址,再进行保存寄存器状态,压栈,函数调用等等实际的操作。
在c,c++年代去完成这个功能是非常麻烦的,但是动态语言却非常简单。
关于执行效率问题。 “静态语言执行效率要比动态语言高”,这句没错。因为一部分cpu计算损耗在了runtime过程中。而静态语言生成的机器指令更简洁。正因为知道这个原因,所以开发语言的人付出很大一部分努力为了保持runtime小巧上。所以objecitve-c是c的超集+一个小巧的runtime环境。
简单理解:“Runtime is everything between your each function call.”
Runtime好比objective-c的灵魂。很多东西都是在这个基础上出现的。所以它是指的你花功夫去理解的。
要理解runtime,首先我们要了解类和对象的内部结构,下面将首先介绍下OC中类与对象的结构层次。
一、首先,从 runtime.h头文件 中找到对 class 与 object 的定义
<span style="color: rgb(128, 128, 128);">///</span><span class="comment"><span style="color: rgb(0, 128, 0);"> An opaque type that represents an Objective-C class.</span></span><span style="color: rgb(0, 128, 0);"></span>
typedef <span style="color: rgb(0, 0, 255);">struct</span> objc_class *<span style="color: rgb(0, 0, 0);">Class;
</span><span style="color: rgb(128, 128, 128);">///</span><span class="comment"><span style="color: rgb(0, 128, 0);"> Represents an instance of a class.</span></span><span style="color: rgb(0, 128, 0);"></span>
<span style="color: rgb(0, 0, 255);">struct</span><span style="color: rgb(0, 0, 0);"> objc_object {
<span class="class"><span class="keyword">Class</span> <span class="title">isa</span>;
};
</span></span><span class="class"><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"> <span class="title">A</span> <span class="title">pointer</span> <span class="title">to</span> <span class="title">an</span> <span class="title">instance</span> <span class="title">of</span> <span class="title">a</span> <span class="title">class</span>.</span>
<span class="title">typedef</span> <span style="color: rgb(0, 0, 255);"><span class="title">struct</span></span> <span class="title">objc_object</span> *<span style="color: rgb(0, 0, 255);"><span class="title">id</span></span>;</span>
由此可见,Class是一个指向objc_class结构体的指针,而id是一个指向objc_object结构体的指针,其成员isa是一个指向objec_class结构体的指针。
二、下面我们再看看头文件中关于objc_class的定义
<span style="color: rgb(0, 0, 255);">struct</span><span style="color: rgb(0, 0, 0);"> objc_class { Class isa; </span><span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 指向metaclass</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 0);"> Class super_class ; </span><span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 指向其父类</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">char</span> *name ; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 类名</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">long</span> version ; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 类的版本信息,初始化默认为0,可以通过runtime函数class_setVersion和class_getVersion进行修改、读取</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">long</span> info; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 一些标识信息,如CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含对象方法和成员变量;CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法;</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">long</span> instance_size ; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 该类的实例变量大小(包括从父类继承下来的实例变量);</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">struct</span> objc_ivar_list *ivars; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 用于存储每个成员变量的地址</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">struct</span> objc_method_list **methodLists ; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 与 info 的一些标志位有关,如CLS_CLASS (0x1L),则存储对象方法,如CLS_META (0x2L),则存储类方法;</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">struct</span> objc_cache *cache; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 指向最近使用的方法的指针,用于提升效率;</span></span><span style="color: rgb(0, 128, 0);"></span> <span style="color: rgb(0, 0, 255);">struct</span> objc_protocol_list *protocols; <span style="color: rgb(0, 128, 0);">//</span><span class="comment"><span style="color: rgb(0, 128, 0);"> 存储该类遵守的协议</span></span><span style="color: rgb(0, 128, 0);"></span> }
由此可见,类比对象的结构体中多了众多的成员,下面详细介绍下objec_class中各成员:
isa:objec_object(对象)中isa指针指向的类结构称为class(也就是该对象所属的类),其中存放着普通成员变量与对象方法 (“-”开头的方法);然而此处isa指针指向的类结构称为metaclass,其中存放着static类型的成员变量与static类型的方法 (“+”开头的方法)。
super_class: 指向该类的父类的指针,如果该类是根类(如NSObject或NSProxy),那么super_class就为NULL。
下面,我们通过一幅图可以看清楚OC中类与对象的继承层次关系:
注意:所有的metaclass中isa指针都是指向根metaclass,而根metaclass则指向自身。根metaclass是通过继承根类产生的,与根class结构体成员一致,不同的是根metaclass的isa指针指向自身。
1、当我们调用某个对象的对象方法时,它会首先在自身isa指针指向的类(class)methodLists中查找该方法,如果找不到则会通过class的super_class指针找到其父类,然后从其methodLists中查找该方法,如果仍然找不到,则继续通过 super_class向上一级父类结构体中查找,直至根class;
2、当我们调用某个类方法时,它会首先通过自己的isa指针找到metaclass,并从其methodLists中查找该类方法,如果找不到则会通过metaclass的super_class指针找到父类的metaclass结构体,然后从methodLists中查找该方法,如果仍然找不到,则继续通过super_class向上一级父类结构体中查 找,直至根metaclass;
关于更多 ios
iOS开发:详解Objective-C runtime
http://mobile.51cto.com/hot-434685.htm