返回
消息流程分析:深入理解iOS中objc_msgSend(下)
IOS
2023-10-14 21:20:51
iOS底层原理07-消息流程分析objc_msgSend(下)
引言
在上一篇文章中,我们分析了objc_msgSend
的快速查找和慢速查找。在两种查找方式都找不到方法实现的情况下,苹果给出了两个建议:动态方法决议和消息转发。本文将深入探讨这两种机制,进一步了解消息发送的底层原理。
动态方法决 resolution
动态方法决议允许类在运行时查找和绑定到方法实现。在使用objc_msgSend
发送消息时,如果快速查找和慢速查找都找不到该方法,就会触发动态方法决 resolution 。
动态方法决 resolution 的过程如下:
- 检查类是否实现了
resolveInstanceMethod:
或resolveClassMethod:
方法。 如果实现了,则调用该方法,并尝试查找并绑定到方法实现。 - 如果类没有实现
resolveInstanceMethod:
或resolveClassMethod:
方法, 则运行时会尝试使用类族中的其他类来查找方法实现。
消息转发
消息转发是另一种机制,允许类处理未处理的消息。在使用objc_msgSend
发送消息时,如果快速查找、慢速查找和动态方法决 resolution 都无法找到该方法,就会触发消息转发。
消息转发的过程如下:
- 检查类是否实现了
forwardInvocation:
方法。 如果实现了,则调用该方法,并传递一个包含消息调用的NSInvocation
对象。类可以处理消息调用并提供自己的实现。 - 如果类没有实现
forwardInvocation:
方法, 则运行时会尝试使用类族中的其他类来转发消息。
比较
动态方法决 resolution 和消息转发都允许类在运行时处理未处理的消息。但是,它们在使用上存在一些关键差异:
- 动态方法决 resolution 主要用于在运行时查找和绑定到方法实现。
- 消息转发 主要用于在运行时处理未处理的消息,并提供自己的实现。
实际应用
动态方法决 resolution 和消息转发在以下情况下非常有用:
- 动态加载类: 动态加载的类可能在编译时不可用,因此可以使用动态方法决 resolution 或消息转发来处理对这些类的消息调用。
- 扩展现有类: 可以通过实现动态方法决 resolution 或消息转发方法来扩展现有类,并为其添加新功能。
- 拦截消息: 可以通过实现动态方法决 resolution 或消息转发方法来拦截消息调用,并对这些调用进行处理或修改。
性能考虑
动态方法决 resolution 和消息转发可能会对性能产生影响。查找和绑定到方法实现需要额外的开销,而消息转发需要额外的处理步骤。因此,在使用这些机制时,应权衡性能成本和灵活性好处。
总结
动态方法决 resolution 和消息转发是两个强大的机制,允许类在运行时处理未处理的消息。它们提供了灵活性,可以查找和绑定到方法实现,或在运行时提供自己的实现。了解这些机制对于理解消息发送的底层原理以及有效利用它们至关重要。