当前位置: 首页 > news >正文

购买深圳网站定制开发重庆学校网站建设

购买深圳网站定制开发,重庆学校网站建设,外贸网站seo推广方案,全屏 单页网站译者前言 总是看到有人说用汇编实现objc_msgSend是为了速度快#xff0c;当然这个不可否认。但是难道没有别的原因#xff1f;于是就看到了这篇文章#xff0c;遂翻译之#xff01;。 我自己的理解就是#xff0c;用汇编实现#xff0c;是为了应对不同的“Calling conven…译者前言   总是看到有人说用汇编实现objc_msgSend是为了速度快当然这个不可否认。但是难道没有别的原因于是就看到了这篇文章遂翻译之。   我自己的理解就是用汇编实现是为了应对不同的“Calling convention”把函数调用前的栈和寄存器的参数、状态设置交给编译器去处理。   先看看原文吧。   原作者: Ari Grant 原文链接: Why objc_msgSend Must be Written in Assembly http://arigrant.com/blog/2014/2/12/why-objcmsgsend-must-be-written-in-assembly   开始   对于Objective-C来说调用一个对象实例的方法也叫作向这个对象实例“发送消息”而每条“消息”在编译阶段都会转变为一次对objc_msgSend函数的调用调用的参数不仅有原本消息的所有参数还有消息的接收者receiver和对应的方法selector。举个例子下面的语句   [receiver message:foo beforeDate:bar];   将会被编译成   objc_msgSend(receiver, selector(message:beforeDate:), foo, bar);   对于objc_msgSend函数的实现原理前人已经做了大量的探索。所以本文将会把重点放在objc_msgSend的一个之前没有太受到关注的点上那就是   objc_msgSend是不可能用Objective-C、C或者C实现的。   THE RETURN TYPE – 返回类型   先看看如下两行代码   NSUInteger n [array count]; id obj [array objectAtIndex:6];   直观上看将会被编译成   NSUInteger n objc_msgSend(array,  selector(count)); id obj objc_msgSend(array, selector(objectAtIndex:), 6);   但是实际上这是不可能的因为没有函数可以同时满足这两个调用。而且它的返回值也不能同时是NSUInteger和id。   而且上面的代码也是无法编译通过的。那么加上类型转换怎么样   NSUInteger n (NSUInteger (*)(id, SEL))objc_msgSend(array,  selector(count)); id obj (id (*)(id, SEL, NSUInteger))objc_msgSend(array, selector(objectAtIndex:), 6);   这下可以编译通过了虽然看起来不直观。。。 objc_msgSend是一个Public的函数在里声明如果你想直接调用它就必须按照上面的格式加上强制类型转换要不然是无法编译通过的。但是objc_msgSend到底是如何实现来支持各种返回类型的本文后面会讲到。   THE IMP – 方法对应的函数指针   objc_msgSend函数的本质很简单传入一个接受者对象实例receiver和方法名selector它就会按照以下步骤执行译者注只是最粗略的步骤。   获取receiver得类Class 在Class的方法列表method table里面查找对应selector的方法实现 找到的话就调用返回 找不到就在其父类中找重复前面的步骤直到没有父类为止   整个流程很简单沿着继承链向上找到方法selector对应的函数指针即可也就是IMP。同时在每层Class中都有缓存加快后续的方法查找。但是这也只是objc_msgSend的实现细节所以接着往下看。   THE ARG TYPES AND COUNT – 参数类型和数量   简单来说当objc_msgSend找到对应的函数指针后只要用传入的参数调用这个函数即可。剩下来的就是找到一种方法可以调用任意参数类型、数量的任意函数。   参数的数量很容易计算。然后我们可以把所有的参数都放入varargs然后调用函数时传入即可。但是这样的话每个Objective-C的方法都必须在其prologue译者注函数执行具体的“任务”前所做的准备环节里面把所有的参数从varargs里面提取出来。   这种把参数打包到varargs里面然后又取出来的办法显然是非常糟糕的同时也是不必要的。   在C语言中调用一个函数会被编译成对应的汇编语言指令首先是设置参数把参数放到寄存器、栈上然后用如jump或者call的指令跳到具体的函数代码地址处。如果我们想支持任意类型的函数类型我们就必须写一个switch语句把所有的参数组合情况都包含起来这样才能正确的为任何形式的函数设置参数译者注即按照某种“规范”、“约定”把参数依次存放到“约定”的寄存器、栈上这显然是没有扩展性的更是不可能的。   UNWINDING THE CALL – 拆解调用   objc_msgSend的解决办法主要依据的是当objc_msgSend被调用时所有的参数已经被设置好了。   换一种方式来说就是在objc_msgSend开始执行时栈帧stack frame的状态、数据和各个寄存器的组合形式、数据跟调用具体的函数指针IMP时所需的状态、数据是完全一致的   如下这行代码   id obj objc_msgSend(array, selector(objectAtIndex:), 6);   在调用objc_msgSend时需要设置三个参数分别是被调用方receiver、方法名selector和最后一个整型参数6。这和具体的方法函数IMP的参数顺序、类型是完全一致的也就是说调用objc_msgSend前设置的栈、寄存器的状态、数据正是调用具体的方法函数时需要的状态   所以当objc_msgSend找到要调用的函数实现IMP后只需要把所有的对栈、寄存器的操作“倒”回到objc_msgSend执行开始的状态类似于函数执行完成return返回前做的“收尾处理”工作一样即epilogue直接jump/call到IMP函数指针对应的地址执行指令即可因为所有的参数已经被设置好了。   同时当selector对应的IMP执行完成后返回值也被正确的设置好了在x86平台上返回值被设置到了指定的寄存器eax/rax里在arm上则是r0寄存器所以我们也不必担心前文提到的不同类型的返回值问题了。   WRAP UP – 总结   把上面提到的所有解释综合起来就是在C语言里面调用函数必须在编译时就知道调用的“状态”而这些“状态”在运行时是无法得出或正确处理的所以必须往底层走用汇编处理。译者注这里不知道咋翻译好。原文是calling a function in C requires the signature to be known for each call-site at compile-timedoing so at run-time is not possible and so one must drop down into assembly and party there instead.   UPDATE – 后续   有人指出objc_msgSend有可能是用GCC的扩展方法__builtin_apply_args__builtin_apply和__builtin_return实现的。这也正指出了一个事实就是这些builtins方法是非常有必要的因为单靠语言本身无法实现这些功能。实现objc_msgSend所需要的技巧也正是实现这些builtins方法所需要的技巧。本文的目的并不是非要将什么是真正的C、什么不是真正的C分个清楚只是为了指出objc_msgSend特殊罢了。   译者总结   开头也说了我的理解是用汇编实现是为了应对不同的“Calling convention”把函数调用前的栈和寄存器的参数、状态设置交给编译器去处理。   嗯以后不要再说用汇编实现只是为了快了。转载于:https://www.cnblogs.com/fengmin/p/5619115.html
http://www.pierceye.com/news/109094/

相关文章:

  • 站内优化怎么做建设设计网站
  • 如何建设机器人教育网站上海有名的网络公司
  • 网站二级目录做网站淄博网站建设 很乱
  • 常州做网站企业海口网站开发建设
  • 做php网站用什么软件开发wordpress页面图片轮播图
  • 做网站页面大小多大8上的信息课做网站作业
  • 自己做微网站创欧科技 网站建设
  • 网站设计师大学学什么专业北京燕华工程建设有限公司网站
  • 广州专业网站建设企业wordpress 数据库修改
  • 淮南装饰公司网站建设seo 网站树
  • 设计素材下载网站网络营销课程设计报告
  • 安庆公司做网站搜索引擎收录提交入口
  • 城固网站建设wordpress主题谁的最好
  • 国外建站企业北京鑫创网站建设
  • 网站做视频wordpress插件手动升级
  • wordpress收不到网站没有收款接口网站怎么做收款
  • 信阳做网站推广用tornado做网站
  • 网站开发与数据库ppt成都优化网站建设
  • 毕业设计静态网站建设选题依据企业网络营销的优势
  • 网站图片动态换名网站充值支付宝收款怎么做
  • 蜘蛛网是个什么网站做特卖的购物网站
  • 从零学做网站古典 网站模板
  • h5网站模板开发网站后台哪些功能需要前端配合
  • 网站建设 宜宾佛山企业网站自助建站
  • 苏宁易购网站建设 的定位手机网站制作招聘
  • 个人网站备案申请360老是提示危险网站
  • 建网站哪个好 优帮云自己怎么注册域名
  • 做3ds磁铁卡网站大连旅顺博物馆
  • 邢台市住房和城乡建设局网站大连网站推广机构
  • 网站建设开标书房地产网页设计