返回
iOS Runtime 之 objc_msgSend 慢速查找流程剖析
IOS
2024-02-16 22:16:59
导言
在我的上一篇文章《iOS Runtime 之方法的本质:objc_msgSend 分析(一)》中,我们深入研究了 objc_msgSend 的缓存查找(快速查找)流程。在本文中,我们将继续探讨在没有缓存时的方法列表查找(慢速查找)流程,进一步了解 objc_msgSend 的内部机制。
方法列表查找
当 objc_msgSend 无法在缓存中找到方法时,它会转而进行方法列表查找。这个过程涉及到以下步骤:
- 类查找: objc_msgSend 从接收者对象中获取其类。
- 元类查找: 它使用该类查找其元类。元类包含指向该类方法列表的指针。
- 方法列表扫描: objc_msgSend 遍历方法列表,直到找到与消息名称匹配的方法。
缓存失效
缓存查找失败的原因可能是:
- 方法在类或其父类中未定义。
- 方法已动态添加或删除。
- 运行时环境发生了变化。
慢速查找性能优化
为了优化慢速查找的性能,Objective-C 运行时采用了以下技术:
- 延迟绑定: 方法在第一次被调用时才被绑定到类。这允许运行时动态加载方法,而不需要预先加载整个方法列表。
- 方法缓存: 当一个方法被找到后,它将被缓存以供将来使用。这减少了后续查找的开销。
示例代码
让我们通过一个示例代码来演示慢速查找流程:
@interface MyClass : NSObject
- (void)myMethod;
@end
@implementation MyClass
- (void)myMethod {
NSLog(@"Hello from myMethod!");
}
@end
int main() {
MyClass *myObject = [[MyClass alloc] init];
[myObject myMethod];
return 0;
}
在上面的示例中,当 myObject 调用 myMethod 时,objc_msgSend 将首先在缓存中查找该方法。由于这是一个新的方法,因此缓存中不存在。然后,它将执行方法列表查找,并在 MyClass 中找到 myMethod。该方法随后将被绑定到 MyClass 并缓存以供将来使用。
结论
通过了解 objc_msgSend 的慢速查找流程,我们获得了对 Objective-C 运行时方法查找机制的更深入理解。这种方法列表查找虽然比缓存查找速度较慢,但它提供了动态和可扩展的方法查找,是 Objective-C 语言强大功能的关键组成部分。