Objective-C 消息转发

消息机制进入转发阶段是OC消息机制最后一个阶段,如果消息处理失败,程序将会崩溃,这个阶段分3个阶段进行,如图:


图片来源于西瓜视频.png

一消息动态解析阶段

这个阶段主要是添加了新的方法处理消息,如果成功则消息处理成功,如果没有进入下一个阶段.
消息动态方法解析时会重载
+(BOOL)resolveInstanceMethod::实例方法动态解析
+(BOOL)resolveClassMethod :内方法动态解析

// 消息动态解析
   [self performSelector:@selector(messageAutosolve)];

+(BOOL)resolveInstanceMethod:(SEL)sel
{
    if (sel == @selector(messageAutosolve)) {
        class_addMethod([self class], sel, (IMP)messageAutosolve, "v@:");
        return YES;
    }
    
    return [super resolveInstanceMethod:sel];
}

void messageAutosolve(id obj,SEL _cmd){
    NSLog(@"调用");
    
}

二 消息接受者重定向

当动态解析失败后,runtime会找到新的消息接受者,如果成功找到则消息处理成功,反之进入下一个阶段.
重定向实例方法的消息接受者
- (id)forwardingTargetForSelector:(SEL)aSelector
重定向类方法的消息接受者
+(id)forwardingTargetForSelector:(SEL)aSelector

// ViewController 没有实现这个类方法
[ViewController classFunciton];
// 不进行动态类方法解析
+(BOOL)resolveClassMethod:(SEL)sel
{
    return YES;
}

// 消息接受者重定向到StudentModel
+(id)forwardingTargetForSelector:(SEL)aSelector{
    
    if (aSelector ==  @selector(classFunciton)) {
//  classFunciton在StudentModel实现
        return [StudentModel class];
    }
    
    return [super forwardingTargetForSelector:aSelector];
}

三 消息重定向

这个阶段也是给消息找新的接受者receive,如果找到则消息处理成功,反之消息处理失败,程序崩溃.
//获取类方法的签名
+(NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector
// 获取实例方法签名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
// 重定向类方法
+ (void)forwardInvocation:(NSInvocation *)anInvocation
// 重定向实例方法
- (void)forwardInvocation:(NSInvocation *)anInvocation

//当前类并没有实现这个方法
    [self testInstahceFunciton];
  // 没有动态解析testInstahceFunciton
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    return YES;
}

// 也没有重定向消息接收者
- (id)forwardingTargetForSelector:(SEL)aSelector{
    
    return nil;
}

// 重定向实例testInstahceFunciton方法
- (void)forwardInvocation:(NSInvocation *)anInvocation{
    SEL sel = anInvocation.selector;
    
    StudentModel *model = [StudentModel new];
    
    if ([model respondsToSelector:sel]) {
        [anInvocation invokeWithTarget:model];
    }else{
        // 重定向失败
        [self doesNotRecognizeSelector:sel];
    }
}

你可能感兴趣的:(Objective-C 消息转发)