oc是一个全动态语言,oc的一切都是基于runtime实现的!
oc是一个全动态语言,oc的一切都是基于runtime实现的!
从以下三方面来理解runtime吧!
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://www.cnblogs.com/hanjun/archive/2013/04/08/3006999.html
oc是一个全动态语言,oc的一切都是基于runtime实现的!的更多相关文章
- 什么是动态语言 OC 的runtime
OC是一门 动态语言. 问题来了.什么是动态语言? 与之相对的静态语言? 学习C++的时候,记得一个名词:“运行时的动态绑定”. 这个是 “多态”的概念. 简单提一下:关键:类指针可以指向本类,或者其 ...
- atitit.提升开发效率---动态语言总结
atitit.提升开发效率---动态语言总结 ruby,python 都不错,就是语法不好, 应用不广泛,文档,工具都非常少,不推荐... php狠不错,就是高级特性不行.. 看来子有.net/jav ...
- 02. oc语言是动态语言
参照着知乎上大神们给的解释,(https://www.zhihu.com/question/19918532)自己要总结下知识: 自己初级并没有理解 动态.静态.强类型.弱类型 语言的这些含义,区分. ...
- 41 (OC)* OC的理解与动态特性
1:动态类型(Dynamic typing),动态绑定(Dynamic binding)和动态加载(Dynamic loading). 动态类型:即运行时再决定对象的类型.简单说就是id类型.id类型 ...
- 为什么可以说Java语言是准动态语言?
什么是动态语言? 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如JavaScript便是一个典型的动态语言. 除此之外如Ruby.Python ...
- 是否含有RTTI(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
- Azure Table storage 之改进DynamicTableEntity类为其添加动态语言扩展
在之前的一篇文章中提到,storage类库中包含一个可以用来动态获取Azure table storage 表结构的类-DynamicTableEntity. 我们可以通过这个类,我们无需为每一个表提 ...
- Web服务器和动态语言如何交互--CGI&FastCGI&FPM浅谈
一个用户的Request是如何经过Web服务器(Apache,Nginx,IIS,Light)与后端的动态语言(如PHP等)进行交互并将结果返回给用户的呢? 本文浅谈个人观点,可能有误,欢迎拍砖,共同 ...
- C# 动态语言特性,dynamic 关键字研究
1 动态语言简介 支持动态特性的语言现在大行其道,并且有继续增长的趋势.比如 Ruby 和 Python, 还有天王级的巨星 --- JavaScript. 现在一个程序员说自己对 Jav ...
随机推荐
- fragment 数据传递,传值,通信
[原][Fragment精深系列4]Fragment与Activity之间的数据交互 2015-5-26阅读389 评论0 以下内容来自于自己的实践和网络资料的整理,希望对你有帮助. 一.Acti ...
- DNS与获取
今天翻看twitter的源码的时候看到了一下内容: <link rel=”dns-prefetch” href=”http://a0.twimg.com”/> <link rel=” ...
- 【BZOj 3670】【UOJ #5】【NOI 2014】动物园
http://www.lydsy.com/JudgeOnline/problem.php?id=3670 http://uoj.ac/problem/5 可以建出"KMP自动机"然 ...
- hibernate--ID生成策略--annotation
annotation: @GeneratedValue a) 自定义ID b)auto: 对mysql默认使用auto_increment, 对oracle使用hibernate_sequence c ...
- javascript books
脑子里突然冒出这么一句话: “反射 是一种 代理!!!”,javascript ECMScript 6中也开始实现 Reflect 了. php的动态代理, 反射方面,在很多框架中都用到了.也是很多框 ...
- Jetty实战之 嵌入式Jetty运行Servlet
http://blog.csdn.net/kongxx/article/details/7230080 Jetty实战之 嵌入式Jetty运行Servlet 分类:JettyJava (19530) ...
- MFC中PeekMessage的使用,非阻塞消息循环
在程序设计的时候经常要进行一个数据循环,比如播放音乐需要循环的向缓冲区里面写入数据,在这个时候比较通用的方法是建立一个线程做事情,但是有时候不想创建多线程就可以使用微软提供的PeekMessage方法 ...
- CodeForces 622B The Time
水题. #include <stdio.h> #include <algorithm> #include <string.h> #include <queue ...
- Eclipse PHP 代码无法自动提示函数
在 linux 系统的 workwpace 里按 ctrl+h,显示出隐藏的文件,找到 .metadata 文件夹,然后将该文件夹删除,再重启 Eclipse 即可.其实它会将之前 Eclipse 连 ...
- STM32+NRF24L01无线(转)
源:STM32+NRF24L01无线 硬件SPI和模拟SPI源码: nrf24发送(模拟SPI)BHS-STM32.rar nrf24接收(模拟SPI)BHS-STM32.rar nrf24发送(硬件 ...