Objective-C(OC)是一门面向对象的编程语言,它在消息传递和方法调用方面具有独特的机制 。在OC中,对象通过消息来调用方法 , 而不是像传统的编程语言那样直接调用函数 。本文将深入探讨OC的消息发送和转发机制原理 , 包括其基本概念、实现过程、代码示例以及实际应用场景 。
文章插图
第一步:什么是消息发送和转发机制?在Objective-C中,对象之间的通信是通过消息传递来实现的 。当一个对象想要调用另一个对象的方法时,它会发送一个消息,然后由接收消息的对象来响应这个消息 。这种方式与传统的函数调用不同 , 使得OC具有更高的动态性和灵活性 。
【OC消息发送和转发机制原理】消息发送和转发机制分为三个阶段:
- 消息发送(Message Sending): 当一个对象收到一个消息时 , 它首先会在自己的方法列表中查找是否有与消息对应的方法 。如果找到了,就会执行该方法;如果找不到,就会进入下一阶段 。
- 消息转发(Message Forwarding): 如果对象无法找到与消息对应的方法,它将进入消息转发过程 。在这个阶段,对象有机会将消息转发给其他对象 。
- 未知消息处理(Handling Unknown Messages): 如果经过消息转发仍未找到合适的方法,系统将调用-doesNotRecognizeSelector:方法,该方法默认会引发异常 , 但也可以由开发者进行重写以执行其他操作 。
- 创建消息: 当一个对象想要调用方法时,它会创建一个消息 , 包括消息的接收者、方法名(选择器)以及方法的参数 。
- 查找方法: 对象会在自己的方法列表(方法分发表)中查找是否存在与消息对应的方法 。方法分发表是一个映射,将选择器与方法的实现关联起来 。
- 调用方法: 如果找到了与消息对应的方法,对象将直接调用该方法并执行 。如果找不到,消息将进入消息转发阶段 。
- 消息转发的开始: 对象收到无法处理的消息后,会调用-forwardingTargetForSelector:方法,该方法允许对象将消息转发给其他对象 。如果返回一个有效的对象,则消息将被转发给该对象 。
- 备用接收者: 如果-forwardingTargetForSelector:方法返回nil,对象会继续查找是否存在备用接收者(Alternate Receiver),这通常是另一个对象 。备用接收者可以通过覆盖+ (id)forwardingTargetForSelector:(SEL)aSelector类方法来指定 。
- 动态方法解析: 如果没有备用接收者或备用接收者也无法处理消息,对象将调用+resolveInstanceMethod:或+resolveClassMethod:方法来动态添加方法 。这允许开发者在运行时为对象添加新方法 。
- 完整的消息转发: 如果前面的步骤都失败 , 对象将调用-forwardInvocation:方法,将消息以NSInvocation对象的形式传递给该方法 。在-forwardInvocation:方法中,开发者可以手动处理消息的转发,包括将消息发送给其他对象或执行其他操作 。
#import <Foundation/Foundation.h>@interface MyObject : NSObject- (void)methodA;@end@implementation MyObject- (void)methodA {NSLog(@"Method A is called");}@endint mAIn(int argc, const char * argv[]) {@autoreleasepool {MyObject *obj = [[MyObject alloc] init];// 调用已存在的方法[obj methodA]; // 输出 "Method A is called"// 调用不存在的方法[obj methodB]; // 触发消息转发// 使用动态方法解析添加方法class_addMethod([MyObject class], @selector(methodB), class_getMethodImplementation([MyObject class], @selector(methodA)), "v@:");// 再次调用方法[obj methodB]; // 输出 "Method A is called"}return 0;}
在这个示例中,我们首先创建了一个MyObject类 , 其中包含了methodA方法 。然后,我们创建了一个对象obj , 并尝试调用methodA方法,这是一个已存在的方法 。
推荐阅读
- Oracle 通过向量存储和全新的生成式 AI 功能,持续推动 MySQL HeatWave 创新
- Docker 推出生成式 AI 堆栈和 Docker AI
- Java机器视觉:利用OpenCV进行图像处理和识别
- Spring Cloud微服务架构:构建弹性和可伸缩的云原生应用
- 杭州亚运会大火背后,是网安和黑产的疯狂对抗
- 缓存的力量:提升API性能和可扩展性
- 如何改QQ密码和账号 如何改qq密码
- 跑步后脚趾甲变黑?深入了解原因和解决方案
- 梦见和父母吵架 吵得特别激烈 梦见和父母吵架
- 如何提高记忆 如何提高记忆力和专注力的方法