二、CLASS消息机制 参考文档Cocoa深刻检出消息机制
1,首先去该类的方法 cache 中查找,若是找到了就返回它;
2,若是没有找到,就去该类的方法列表中查找。若是在该类的方法列表中找到了,则将 IMP 返回,并将它加入cache中缓存起来。根据最近使用原则,这个方法再次调用的可能性很大,缓存起来能够节省下次调用再次查找的开销。
3,若是在该类的方法列表中没找到对应的 IMP,在经过该类结构中的 super_class指针在其父类结构的方法列表中去查找,直到在某个父类的方法列表中找到对应的IMP,返回它,并加入cache中;
4,若是在自身以及全部父类的方法列表中都没有找到对应的 IMP,则看是否是能够进行动态方法决议;
5,若是动态方法决议没能解决问题,进入消息转发流程c++
1、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环境开发人员已经帮你处理了这些问题。缓存