什么是转发机制
当对象接收到与其方法不匹配的消息时,通过消息转发机制可以使对象执行用户预定义的处理过程。
消息转发小例子
先看下转发图解
一步步构建
- 建立DoMyWork类
DoMyWork.h
#import <Foundation/Foundation.h>
@interface DoMyWork : NSObject
@property (nonatomic, assign) NSString *myWork;
- (instancetype)initWithMyWork:(NSString *)myWork;
@end
DoMyWork.m
#import "DoMyWork.h"
#import "WorkHelper.h"
@implementation DoMyWork
{
// 我知道这个类的对象可为我做一些事情
WorkHelper *_helper;
}
// 初始化方法
- (instancetype)initWithMyWork:(NSString *)myWork
{
if (self = [super init])
{
_myWork = myWork;
_helper = [[WorkHelper alloc] init];
}
return self;
}
// 重写NSObject类的这个方法,实现快速转发
- (id)forwardingTargetForSelector:(SEL)aSelector
{
if ([_helper respondsToSelector: aSelector])
{
NSLog(@"我干不了,我要找人帮忙!");
return _helper;
}
return nil;
}
@end
- 建立WorkHelper类
WorkHelper.h
#import <Foundation/Foundation.h>
@interface WorkHelper : NSObject
- (void)helpDoSomething:(NSString *)something;
@end
WorkHelper.m
#import "WorkHelper.h"
@implementation WorkHelper
- (void)helpDoSomething:(NSString *)something
{
NSLog(@"WorkHelper help do %@", something);
}
@end
- 使用转发
main.m
#import <Foundation/Foundation.h>
#import "DoMyWork.h"
int main(int argc, const char * argv[]) {
@autoreleasepool
{
DoMyWork *dowork = [[DoMyWork alloc] initWithMyWork: @"洗衣服"];
[dowork helpDoSomething: dowork.myWork];
}
return 0;
}
我们发现xcode报错了,是因为 helpDoSomething这个方法没有在DoMyWork.h文件中声明,我们要去声明它。实际它是在WorkHelper.h文件中声明的。那么我们可以在DoMyWork.h文件中声明下(不必再DoMyWork.m实现它)。之后,出现了预期的结果。
总结
实现快速转发需要明确以下几点:
- 我需要知道哪个类(WorkHelper)的对象可以对我发出的消息进行响应。
- 在需要转发的类(DoMyWork)复合可以响应消息的类(WorkHelper)。
- 在需要转发的类(DoMyWork)重写forwardingTargetForSelector:(SEL)方法。
之后OC在运行时就可以自动转发你发送的当前对象无法响应的消息。当然,若你转发到的对象任然无法进行响应,那么你也就无法得到正确的结果。