iOS – Runtime-消息机制-objc_msgSend()

💡 原文中文,约9700字,阅读约需23分钟。
📝

内容提要

本文介绍了iOS中的音讯机制-objc_msgSend的履行流程,包括音讯发送、动态办法解析和音讯转发三个阶段。在动态办法解析阶段,开发者可以动态添加办法。在音讯转发阶段,可以自定义逻辑处理音讯。此外,还介绍了super的本质和使用方法。

🔎

延伸解读

动态方法解析的触发条件与重走流程

动态方法解析仅在消息发送阶段找不到方法实现时触发。开发者实现+resolveInstanceMethod:或+resolveClassMethod:动态添加方法后,系统会重新从receiverClass的缓存开始执行消息发送流程。这意味着动态添加的方法会被缓存,后续调用效率更高。若解析返回NO,则进入消息转发阶段。

消息转发三个阶段的选择策略

消息转发提供三个递进阶段:forwardingTargetForSelector:可快速将消息转发给备用接收者;methodSignatureForSelector:与forwardInvocation:配合可自定义复杂逻辑,如修改参数或转发给多个对象。前者效率更高,后者更灵活。若均未处理,则抛出unrecognized selector异常。

类方法消息转发的实现要点

类方法的消息转发同样支持,但需使用加号版本的方法。在动态解析类方法时,需通过object_getClass(self)获取元类对象,并向其添加方法。在转发阶段,forwardingTargetForSelector:和methodSignatureForSelector:也需使用加号版本,返回类对象或类方法签名。

super调用的本质与查找顺序

super调用底层转换为objc_msgSendSuper2,传入objc_super结构体,包含receiver和super_class。receiver仍是当前对象self,但方法查找从super_class开始。因此[super class]与[self class]输出相同,因为class方法最终在NSObject中找到,且消息接收者都是self。

❓

Q&A

objc_msgSend的执行流程分为哪几个阶段?

objc_msgSend的执行流程分为音讯发送、动态办法解析和音讯转发三个阶段。

如何在动态方法解析阶段动态添加方法?

可以使用+resolveInstanceMethod:和+resolveClassMethod:方法来动态添加实例方法和类方法。

音讯转发阶段的处理流程是什么?

音讯转发阶段首先调用forwardingTargetForSelector:,如果未处理则调用methodSignatureForSelector:,最后调用forwardInvocation:。

super的本质是什么?

super的本质是通过objc_msgSendSuper2函数调用,super会多传一个super_class,影响查找顺序。

如何使用forwardInvocation:自定义逻辑处理消息?

在forwardInvocation:方法中,开发者可以自定义任何逻辑来处理未被解析的消息。

动态方法解析后会发生什么?

动态方法解析后会重新走音讯发送的流程,从receiverClass的cache中查找方法。

🏷️

标签

➡️

继续阅读