- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
从C的伪代码到汇编,动手实现objc_msgSend分析
从C的伪代码到汇编,动手实现objc_msgSendobjc_msgSend 函数支撑了我们使用 Objective-C 实现的一切。Gwynne Raskind,Friday QA 的读者,建议我谈谈 objc_msgSend 的内部实现。要理解某件事还有比自己动手实现一次更好的方法吗?咱们来自己动手实现一个 objc_msgSend。Tramapoline! Trampopoline! (蹦床)当你写了一个发送 Objective-C 消息的方法:[obj?message]?编译器会生成一个 objc_msgSend 调用:objc_msgSend(obj,?@selector(message));?之后 objc_msgSend 会负责转发这个消息。它都做了什么?它会查找合适的函数指针或者 IMP,然后调用,最后跳转。任何传给 objc_msgSend 的参数,最终都会成为 IMP 的参数。 IMP 的返回值成为了最开始被调用的方法的返回值。因为 objcmsgSend 只是负责接收参数,找到合适的函数指针,然后跳转,有时管这种叫做 trampoline(译注:[蹦床](/wiki/Trampoline(computing)). 更通用的来说,任何一段负责把一段代码转发到另一处的代码,都可以被叫做 trampoline。这种转发的行为使 objc_msgSend 变得特殊起来。因为它只是简单的查找合适的代码,然后直接跳转过去,这相当的通用。传入任何参数组合都可以,因为它只是把这些参数留给 IMP 去读取。返回值有些棘手,但最终都可以看成 objc_msgSend 的不同变种。不幸的是,这些转发行为都不能用纯 C 实现。因为没有方法可以将传入 C 函数的泛参(generic parameters)传给另一个函数。 你可以使用变参,但是变参和普通参数的传递方法不同,而且慢,所以这不适合普通的 C 参数。如果要用 C 来实现 objc_msgSend,基本样子应该像这样:id?objc_msgSend(id?self,?SEL?_cmd,?...)?{?Class?c?=?object_getClass(self);?IMP?imp?=?class_getMethodImplementation(c,?_cmd);?return?imp(self,?_cmd,?...);?}?这有点过于简单。事实上会有一个方法缓存来提升查找速度,像这样:id?objc_msgSend(id?self,?SEL?_cmd,?...)?{?Class?c?=?object_getClass(self);?IMP?imp?=?cache_lookup(c,?_cmd);?if(!imp)?imp?=?class_getMethodImplementation(c,?_cmd);?return?imp(self,?_cmd,?...);?}?通常为了速度,cache_lookup 使用 inline 函数实现。汇编在 Apple 版的 runtime 中,为了最大化速度,整个函数是使用汇编实现的。在 Objective-C 中每次发送消息都会调用 objc_msgSend,在一个应用中最简单的动作都会有成千或者上百万的消息。为了让事情更简单,我自己的实现中会尽可能少的使用汇编,使用独立的 C 函数抽象复杂度。汇编代码会实现下面的功能:id?objc_msgSend(id?self,?SEL?_cmd,?...)?{?IMP?imp?=?GetImplementation(self,?_cmd);?imp(self,?_cmd,?...);?}??GetImplementation?可以用更可读的方式工作。?汇编代码需要:1. 把所有潜在的参数存储在安全的地方,确保 GetImplementation 不会覆盖它们。2. 调用 GetImplementation。3. 把返回值保存在某处。4. 恢复所有的参数值。5. 跳转到 GetImplementation 返回的 IMP。让我们开始吧!这里我会尝试使用 x86-64 汇编,这样可以很方便的在 Mac 上工作。这些概念也可以应用于 i386 或者 ARM。这个函数会保存在独立的文件中,叫做 msgsend-asm.s。这个文件可以像源文件那样传递给编译器,然后会被编译并链接到程序中。第一件事要做的是声明全局的符号(global symbol)。因为一些无聊的历史原因,C 函数的 global symbol 会在名字前有个下划线:.globl?_objc_msgSend?_objc_msgSend:?编译器会很高兴的链接最近可使用的(nearest available) objc_msgSend。简单
您可能关注的文档
- 仁爱版八年级英语下册-Unit7Topic2SectionD(共20张PPT)分析.ppt
- 仁爱版英语八年级上册期末复习:分析.ppt
- 仁爱版英语八年级下学期全册教案分析.doc
- 仁爱英语七年级上册期中测试题分析.doc
- 仁爱英语七年级下册unit7单元测试(含答案及解释)分析.doc
- 仁爱版英语八年级下册Unit5Topic1SectionD分析.ppt
- 仁爱版八年级下册Unit7Topic2SectionB分析.ppt
- 仁爱版英语八年级下册_Unit_6_Topic_2_Section_C__阅读分析.ppt
- 仁爱英语九年级上册Unit3Topic1SectionD分析.ppt
- 仁爱英语九年级unit1topic1sectionB分析.ppt
最近下载
- TZS 0678—2025《生物安全实验室工作人员本底血清样本管理规范》(水印版).pdf VIP
- 2025年工会基础知识考试题库及参考答案(通用版).pptx VIP
- 抗菌药物的合理使用课件(共37张PPT).pptx VIP
- 急危重症患者护理抢救流程与规范.pptx VIP
- 平衡梁组件的承压检测装置.pdf VIP
- 2025年最新工会基础知识考试题库及参考答案(通用版).pptx VIP
- 44-无机复合聚苯不燃保温板应用技术规程T_CIEEMA002-2020.pptx VIP
- 供货方案及质量保证措施 .docx VIP
- 殡葬领域突出问题专项整治行动实施方案.docx VIP
- T_ACEF 207—2025(工业有机废气收集系统技术规范).pdf
文档评论(0)