欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > Message forwarding mechanism (消息转发机制)

Message forwarding mechanism (消息转发机制)

2024/10/23 6:13:36 来源:https://blog.csdn.net/qfeung/article/details/139440719  浏览:    关键词:Message forwarding mechanism (消息转发机制)

在这里插入图片描述

iOS的消息转发机制

iOS的消息转发机制是在消息发送给对象时,找不到对应的实例方法的情况下启动的。消息转发允许对象在运行时处理无法识别的消息,提供了一种动态的、灵活的消息处理方式。

消息转发机制主要分为三个阶段:

  1. 动态方法解析
  2. 快速转发
  3. 标准转发

1. 动态方法解析

在这个阶段,运行时系统会询问对象是否能动态添加方法来处理未知消息。可以通过实现 +resolveInstanceMethod:+resolveClassMethod: 方法来动态添加方法实现。

+ (BOOL)resolveInstanceMethod:(SEL)sel {if (sel == @selector(someMethod)) {class_addMethod([self class], sel, (IMP)someMethodImplementation, "v@:");return YES;}return [super resolveInstanceMethod:sel];
}void someMethodImplementation(id self, SEL _cmd) {NSLog(@"Dynamically added method");
}

2. 快速转发

如果动态方法解析失败,运行时会调用 -forwardingTargetForSelector: 方法,询问对象是否有其他对象可以处理该消息。通过返回另一个对象的实例,消息可以转发给该实例。

- (id)forwardingTargetForSelector:(SEL)aSelector {if (aSelector == @selector(someMethod)) {return alternateObject;}return [super forwardingTargetForSelector:aSelector];
}

3. 标准转发

如果前两个阶段都失败,运行时会调用 -methodSignatureForSelector:-forwardInvocation: 方法进行标准消息转发。首先,通过 -methodSignatureForSelector: 方法获取方法签名,然后在 -forwardInvocation: 方法中处理消息。

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {if (aSelector == @selector(someMethod)) {return [NSMethodSignature signatureWithObjCTypes:"v@:"];}return [super methodSignatureForSelector:aSelector];
}- (void)forwardInvocation:(NSInvocation *)anInvocation {if ([alternateObject respondsToSelector:[anInvocation selector]]) {[anInvocation invokeWithTarget:alternateObject];} else {[super forwardInvocation:anInvocation];}
}

图示

为了更好地理解这个过程,下面是一个示意图:

+----------------------+
|        Sender        |
+----------------------+|| Message: someMethodv
+----------------------+
|     Receiver         |
+----------------------+
|                      |
| -resolveInstanceMethod:
|     - Can add method? ----> YES (add method)
|                      |
|                      v
|  NO                  |
|                      |
| -forwardingTargetForSelector:
|     - Other object to handle? ----> YES (forward to other object)
|                      |
|                      v
|  NO                  |
|                      |
| -methodSignatureForSelector:
|     - Get method signature ----> Signature or nil
|                      |
|                      v
|  Signature           |
|                      |
| -forwardInvocation:
|     - Handle invocation ----> Forward or error
+----------------------+

示例代码

下面是一个完整的示例代码,展示如何使用消息转发机制:

#import <objc/runtime.h>@interface SQIAlternateObject : NSObject
- (void)someMethod;
@end@implementation SQIAlternateObject
- (void)someMethod {NSLog(@"AlternateObject handling someMethod");
}
@end@interface MyObject : NSObject
@end@implementation MyObject {SQIAlternateObject *alternateObject;
}- (instancetype)init {self = [super init];if (self) {alternateObject = [[SQIAlternateObject alloc] init];}return self;
}+ (BOOL)resolveInstanceMethod:(SEL)sel {if (sel == @selector(someMethod)) {class_addMethod([self class], sel, (IMP)someMethodImplementation, "v@:");return YES;}return [super resolveInstanceMethod:sel];
}void someMethodImplementation(id self, SEL _cmd) {NSLog(@"Dynamically added method");
}- (id)forwardingTargetForSelector:(SEL)aSelector {if (aSelector == @selector(someMethod)) {return alternateObject;}return [super forwardingTargetForSelector:aSelector];
}- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {if (aSelector == @selector(someMethod)) {return [NSMethodSignature signatureWithObjCTypes:"v@:"];}return [super methodSignatureForSelector:aSelector];
}- (void)forwardInvocation:(NSInvocation *)anInvocation {if ([alternateObject respondsToSelector:[anInvocation selector]]) {[anInvocation invokeWithTarget:alternateObject];} else {[super forwardInvocation:anInvocation];}
}@endint main(int argc, const char * argv[]) {@autoreleasepool {MyObject *obj = [[MyObject alloc] init];[obj someMethod];}return 0;
}

在这个示例中,我们展示了如何通过动态方法解析、快速转发和标准转发来处理 someMethod 方法。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com