返回
消息查找流程(下)- 方法列表的查找(慢速发送流程)
IOS
2024-01-16 21:12:03
慢速发送流程
在上一篇文章中,我们分析了快速发送流程,即当方法缓存命中时如何直接发送消息。然而,在某些情况下,方法缓存可能会失效,比如当方法被覆盖或类被重新编译时。此时,消息发送就会进入慢速发送流程,即_lookUpImpOrForward函数。
慢速发送流程主要分为以下几步:
- 查找方法列表
- 处理方法冲突
- 处理继承
- 发送消息
方法列表的查找
方法列表是存储在类对象中的一个数据结构,其中包含了该类及其父类的所有方法。方法列表的查找过程如下:
- 首先,在当前类的类对象中查找方法。
- 如果在当前类的类对象中找不到方法,则继续在父类的类对象中查找,以此类推,直到找到方法或到达根类。
- 如果在整个继承链中都没有找到方法,则抛出异常。
类方法的查找
类方法是属于类的,而不是属于类的实例的。因此,类方法的查找过程与实例方法的查找过程略有不同。
类方法的查找过程如下:
- 首先,在当前类的类对象中查找类方法。
- 如果在当前类的类对象中找不到类方法,则继续在父类的类对象中查找,以此类推,直到找到类方法或到达根类。
- 如果在整个继承链中都没有找到类方法,则抛出异常。
实例方法的查找
实例方法是属于类的实例的。因此,实例方法的查找过程与类方法的查找过程略有不同。
实例方法的查找过程如下:
- 首先,在当前类的类对象中查找实例方法。
- 如果在当前类的类对象中找不到实例方法,则继续在父类的类对象中查找,以此类推,直到找到实例方法或到达根类。
- 如果在整个继承链中都没有找到实例方法,则抛出异常。
方法冲突的处理
在Objective-C中,方法冲突是指两个或多个方法具有相同的名称和参数列表。方法冲突可能会导致程序运行时出错。
为了处理方法冲突,Objective-C采用了以下两种策略:
- 方法覆盖: 子类可以覆盖父类的方法,即子类可以重新定义父类的方法。当子类覆盖父类的方法时,子类的方法将取代父类的方法。
- 方法重载: Objective-C允许方法重载,即允许两个或多个方法具有相同的名称,但参数列表不同。当调用方法重载时,编译器会根据参数列表来选择要调用的方法。
继承的处理
在Objective-C中,子类可以继承父类的所有方法。子类可以重写父类的方法,也可以添加新的方法。
当子类调用父类的方法时,消息发送机制会先在子类的方法列表中查找方法,如果没有找到,则继续在父类的方法列表中查找,以此类推,直到找到方法或到达根类。
发送消息
当消息发送机制找到要调用的方法后,就会将消息发送给该方法。消息发送过程如下:
- 将接收者对象压入堆栈。
- 将消息选择器压入堆栈。
- 将消息参数压入堆栈。
- 跳转到要调用的方法。
方法执行完毕后,将结果压入堆栈,然后返回调用者。
总结
本文分析了Objective-C中的消息查找流程,重点介绍了慢速发送流程,即当方法缓存命中失败时如何查找方法列表。文章详细讲解了方法列表的查找过程,包括如何查找类方法和实例方法,以及如何处理方法冲突和继承等情况。通过本文,读者将对Objective-C中消息查找机制有更深入的了解,从而更好地理解Objective-C的运行原理。