美文网首页
runtime之消息转发机制

runtime之消息转发机制

作者: hallfrita | 来源:发表于2018-01-11 16:54 被阅读0次

在程序中,调用我们未实现或找不到的方法时,程序就会崩溃,如下

Person *person = [Person new];

//    [person run];

[person performSelector:@selector(run)];

调用person类的run方法时,会报下面错


图1.png

其实,抛异常前,这个消息经过了三件事,我们重写这几个方法,就能很好的改变这些方法的实现,实现消息转发

1、动态添加方法:尝试动态给目标类(比如这个例子为Person)添加一个方法来实现这个未知的selector。

2、消息转发重定向:尝试寻找另一个能够识别该selector的receiver。

3、标准的消息转发:对消息使用NSInvocation对象进行重新包装,给receiver最后一次识别机会。

示意图如下

图2.png

一、动态添加方法 resolveInstanceMethod

我们这里用newRun这个方法替换这个未实现的run

+ (BOOL)resolveInstanceMethod:(SEL)sel {

    NSLog(@"sel = %@", NSStringFromSelector(sel));

    // 1、动态添加方法

    if (sel == @selector(run)) {

        class_addMethod(self, sel, (IMP)newRun, "v@:v");

        return YES;

    }

    return [super resolveInstanceMethod:sel];

}

newRun方法

void newRun(id self,SEL sel, NSString *str) {

    NSLog(@"--------run is implement %@--------", str);

}

二、 消息重定向forwardingTarget

这里将Person的run方法重定向到Animation的run实现

- (id)forwardingTargetForSelector:(SEL)aSelector {

    NSLog(@"%@",NSStringFromSelector(aSelector));

    // 2、消息转发重定向

    if ([NSStringFromSelector(aSelector) isEqualToString:@"run"]) {

        return [Animation new];

    } else {

        return [super forwardingTargetForSelector:aSelector];

    }

}

三、标准的消息转发 forwardInvocation

  // 3、生成方法签名

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {

    NSString *sel = NSStringFromSelector(aSelector);

    if ([sel isEqualToString:@"run"]) {

        return [NSMethodSignature signatureWithObjCTypes:"v@:"];

    } else {

        return [super methodSignatureForSelector:aSelector];

    }

}

// 4、拿到方法签名配发消息

- (void)forwardInvocation:(NSInvocation *)anInvocation {

    NSLog(@"-----%@",anInvocation);

    SEL seletor = [anInvocation selector];

    Animation *anim = [Animation new];

    if ([anim respondsToSelector:seletor]) {

        [anInvocation invokeWithTarget:anim];

    } else {

        [super forwardInvocation:anInvocation];

    }

}

最后,如果跑了这几个方法都没有找到,我么还可以给一个友好的提示

// 5、抛出友好异常
 - (void)doesNotRecognizeSelector:(SEL)aSelector {
     NSString *selStr = NSStringFromSelector(aSelector);
     NSLog(@"%@ dose not recognize.......",selStr);
 }

相关文章

  • runtime系列文章总结

    《iOS Runtime详解(消息机制,类元对象,缓存机制,消息转发)》《消息转发机制与Aspects源码解析》《...

  • Runtime 的应用

    前面我们说到:Runtime 消息传递机制Runtime 消息转发机制Runtime 交换方法今天我们来谈谈Run...

  • Effective Objective-C读后笔记(2)

    11、runtime消息转发机制 runtime的消息转发流程图消息转发 消息转发的示例实现 这里也给大家推荐一篇...

  • iOS - Runtime - 概念和方法交换

    runtime的概述runtime的相关概念runtime消息机制消息传递动态方法解析消息转发runtime的作用...

  • iOS消息转发机制

    消息转发机制: 消息转发机制是相对于消息传递机制而言的。 1、消息(传递)机制 RunTime简称运行时。就是系统...

  • runtime之消息转发机制

    在程序中,调用我们未实现或找不到的方法时,程序就会崩溃,如下 调用person类的run方法时,会报下面错 其实,...

  • OC学习Runtime之消息传递,消息转发机制

    转载自:OC学习Runtime之消息传递,消息转发机制 参考文献:Effective Objective-C No...

  • 转载:runtime之消息转发机制(三)

    Objective-C runtime之消息转发机制(三) 作者:wangzz原文地址:http://blog.c...

  • Runtime知识点整理1

    OC消息机制?消息转发机制流程?什么是Runtime?什么场景下使用? ==============巴拉巴拉......

  • runtime消息转发机制

    消息转发机制基本上分为三个步骤: 1. 动态方法解析 2. 备用接收者 3. 完整转发 我们可以通过控制这三个步骤...

网友评论

      本文标题:runtime之消息转发机制

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