美文网首页
Objective-C 消息转发

Objective-C 消息转发

作者: Hunter琼 | 来源:发表于2018-03-29 10:53 被阅读22次

    前文提到(https://www.jianshu.com/p/588d1d8c3ee1),消息动态方法解析时会重载+(BOOL)resolveInstanceMethod:+(BOOL)resolveClassMethod; 当这两个方法返回NO时,消息转发机制就会触发.
    一 重定向(备援接受者)
    在消息转发之前可以通过-(id)fowardingTargetForSelector:(SEL)aSelecto中把消息转给其它接受者来处理.
    新建RedirectionMessageMethod类

    @interface RedirectionMessageMethod : NSObject
    //被其它接受者处理的方法
    - (void)redirectionMethod:(int)temp;
    
    #import "RedirectionMessageMethod.h"
    #import "OtherHandelMethod.h"
    
    @implementation RedirectionMessageMethod
    - (id)forwardingTargetForSelector:(SEL)aSelector
    {
        if ([NSStringFromSelector(aSelector) isEqualToString:@"redirectionMethod:"]) {
            // 把这个方法转给OtherHandelMethodl类
            OtherHandelMethod *otherTar  = [OtherHandelMethod new];
            return otherTar;
        }
        return [super forwardingTargetForSelector:aSelector];
        
    }
    

    新建OtherHandelMethod类

    #import "OtherHandelMethod.h"
    
    @implementation OtherHandelMethod
    
    - (void)redirectionMethod:(int)temp
    {
        NSLog(@"实现RedirectionMessageMethod过来的方法redirectionMethod:");
        
    }
    

    运行结果

    2018-03-28 10:15:13.051529+0800 OC_Categroy[1015:57719] 实现RedirectionMessageMethod过来的方法redirectionMethod:
    

    二 转发
    当消息转发机制触发时,执行forwardInvocation:;而该方法的参数是NSInvocation类型的对象(封装了原始的消息和消息参数);通过实现该方法对不能处理的消息做一些默认的处理,也可以将消息转发给其它某个对象来处理.当我们重写forwardInvocation:方法时,同时也要重写methodSignatureForSelector:方法,否则抛异常!
    forwardInvocation:方法就像一个不能识别的消息的分发中心,将这些消息转发给不同接收对象。或者它也可以象一个运输站将所有的消息都发送给同一个接收对象。它可以将一个消息翻译成另外一个消息,或者简单的”吃掉“某些消息,因此没有响应也没有错误。forwardInvocation:方法也可以对不同的消息提供同样的响应,这一切都取决于方法的具体实现。该方法所提供是将不同的对象链接到消息链的能力。
    注意: forwardInvocation:方法只有在消息接收对象中无法正常响应消息时才会被调用。 所以,如果我们希望一个对象将negotiate消息转发给其它对象,则这个对象不能有negotiate方法。否则,forwardInvocation:将不可能会被调用。
    将上文提到的消息重定向变成完全转发,需要在OtherHandelMethod创建NSMethodSignature对象

    // 重写methodSignatureForSelector方法 进行完整转发
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
    {
        if ([NSStringFromSelector(aSelector) isEqualToString:@"redirectionMethod:"]) {
            NSMethodSignature *sign = [NSMethodSignature signatureWithObjCTypes:"v@:@"];
            return sign;
        }
        return [super methodSignatureForSelector:aSelector];
        
    }
    

    然后实现forwardInvocation:方法将消息分发给InvocationModel

    // 消息完整转发给InvocationModel类  InvocationModel里面在实现charge:方法
    - (void)forwardInvocation:(NSInvocation *)anInvocation
    {
        InvocationModel *model = [InvocationModel new];
        anInvocation.selector  = NSSelectorFromString(@"charge:");
        if ([model respondsToSelector:[anInvocation selector]]) {
            [anInvocation invokeWithTarget:model];
        }else{
            [super forwardInvocation:anInvocation];
        }
    }
    

    新建InvocationModel类

    #import "InvocationModel.h"
    
    @implementation InvocationModel
    
    - (void)charge:(int)chareInt
    {
        NSLog(@"将redirectionMethod方法转发了");
        
    }
    

    运行结果:

    2018-03-29 10:38:28.380568+0800 OC_Categroy[921:42779] 将redirectionMethod方法转发了
    

    参考文献::http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/

    相关文章

      网友评论

          本文标题:Objective-C 消息转发

          本文链接:https://www.haomeiwen.com/subject/itfycftx.html