Runtime

OC的runtime
优点:
1. 传统的面向过程的语言开发,例如c语言。实现c语言编译器很简单,只要按照语法规则实现一个LALR语法分析器就可以了。 这里我们实现编译器中最最基础和原始的目标之一就是把一份代码里的函数名称,转化成一个相对内存地址,把调用这个函数的语句转换成一个jmp跳转指令。在程序开始运行时候,调用语句可以正确跳转到对应的函数地址。 这样很好,也很直白,但是太死板了。

2. 我们希望灵活,于是需要开发面向对象的语言,例如c++。 c++在c的基础上增加了类的部分。但这到底意味着什么呢?我们在写它的编译器要如何考虑呢?其实,就是让编译器多绕个弯,在严格的c编译器上增加一层类处理的机制,把一个函数限制在它处在的class环境里,每次请求一个函数调用,先找到它的对象, 其类型,返回值,参数等等,确定了这些后再jmp跳转到需要的函数。这样很多程序增加了灵活性同样一个函数调用会根据请求参数和类的环境返回完全不同的结果。增加类机制后,就模拟了现实世界的抽象模式,不同的对象有不同的属性和方法。同样的方法,不同的类有不同的行为! 这里大家就可以看到作为一个编译器开发者都做了哪些进一步的思考。但是还是死板。

3. 希望更加灵活! 于是我们完全把上面类的实现部分抽象出来,做成一套完整运行阶段的检测环境。这次再写编译器,runtime环境注册所有全局的类,函数,变量等等信息,我们可以无限的为这个层增加必要的功能。调用函数时候,会先从这个运行时环境里检测所以可能的参数再做jmp跳转,这就是runtime。编译器开发起来比上面更加弯弯绕,但是这个层极大增加了程序的灵活性。  例如当调用一个函数时候,前2种语言,很有可能一个jmp到了一个非法地址导致程序crash, 但是在这个层次里面,runtime就过滤掉了这些可能性。

缺点:
C++是基于虚拟表支持的确定虚函数调用哪个方法,是编译器做了所有的工作。object c使用运行时,运行库支持进入各种类结构中查找相应的代码以供调用。所以,OC相对C++来说灵活的多,但是也失去了C++的高效率。

不过objective c runtime库提供了一个方法"methodForSelector"来解决这个问题,你可以让动态运行库只查询类表一次找到这个方法,然后把这个方法地址传给一个函数指针,搞定。  
以下演示如何绕过动态绑定的方法:
void (*setter)(id, SEL, BOOL);
int i;
setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];
for ( i = 0; i < 1000, i++ )
    setter(targetList[i], @selector(setFilled:), YES);
何时需要绕过动态绑定?当且仅当一个方法需要调用多次的时候,通过绕过动态绑定,能节约反复通过消息查找方法所需要的时间。

你可能感兴趣的:(Runtime)