美文网首页
runtime中的消息转发

runtime中的消息转发

作者: guoguojianshu | 来源:发表于2019-05-04 19:38 被阅读0次

1动态方法解析

如果一个对象调用了在这个类中方法列表中找不到选择子(SEL),这个时候可以使用为这个选择子添加一个方法

#import "ViewController.h"
#import <objc/runtime.h>
#import <objc/message.h>
@interface ViewController ()

@end

@implementation ViewController
void noParameterMethod (id self , SEL sel);
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self performSelector:@selector(method:) withObject:@"123"];
    [self performSelector:@selector(noParameterMethod)];
}

void method (id self ,SEL sel ,id objc){
    NSLog(@"%@",objc);
}
void noParameterMethod (id self , SEL sel){
    NSLog(@"无参数的函数");
}

+(BOOL)resolveInstanceMethod:(SEL)sel{
    NSLog(@"%@",NSStringFromSelector(sel));
    if ([NSStringFromSelector(sel) hasPrefix:@"method"]) {
        class_addMethod(self, sel, (IMP)method, "v@:@");
        return YES;
    }else if ([NSStringFromSelector(sel) hasPrefix:@"noParameterMethod"]){
        class_addMethod(self, sel, (IMP)noParameterMethod, "v@:");
        return YES;
    }else{
        return [super resolveInstanceMethod:sel];
    }
}

@end
打印信息为

备援接受者

可以把自己不能识别的选择子交给其他对象进行处理

 [self performSelector:@selector(forwardSelecter)];
-(id)forwardingTargetForSelector:(SEL)aSelector{
   NSString * selectorString =  NSStringFromSelector(aSelector);
    if ([selectorString isEqualToString:@"forwardSelecter"]) {
        SecondViewController * vc = [[SecondViewController alloc]init];
        return vc;
    }else{
        return [super forwardingTargetForSelector:aSelector];
    }
}


#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

-(void)forwardSelecter{
    NSLog(@"备源消息转发");
}

完整的消息转发

  [self performSelector:@selector(normalForwardSelector)];
    [self performSelector:@selector(normalForwardPaSelector:) withObject:@"带有参数456"];

-(void)forwardInvocation:(NSInvocation *)anInvocation{
    SEL sel =  anInvocation.selector;
    
    SecondViewController * vc = [[SecondViewController alloc]init];
    if ([vc respondsToSelector:sel]) {
        [anInvocation invokeWithTarget:vc];
    }else{
        [self doesNotRecognizeSelector:sel];
    }
}

-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
 NSMethodSignature * signature =   [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [NSMethodSignature signatureWithObjCTypes:"v@:"];
    }
    return signature;
}


#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

-(void)forwardSelecter{
    NSLog(@"备源消息转发");
}
-(void)normalForwardSelector{
    NSLog(@"完整的消息转发");
}
-(void)normalForwardPaSelector:(NSString *)objc{
    NSLog(@"%@",objc);
}
@end

Objective-C 中给一个对象发送消息会经过以下几个步骤:

在对象类的 dispatch table 中尝试找到该消息。如果找到了,跳到相应的函数IMP去执行实现代码;

如果没有找到,Runtime 会发送 +resolveInstanceMethod: 或者 +resolveClassMethod: 尝试去 resolve 这个消息;

如果 resolve 方法返回 NO,Runtime 就发送-forwardingTargetForSelector: 允许你把这个消息转发给另一个对象;

如果没有新的目标对象返回, Runtime 就会发送-methodSignatureForSelector:-forwardInvocation:消息。你可以发送 -invokeWithTarget:消息来手动转发消息或者发送 -doesNotRecognizeSelector: 抛出异常。

相关文章

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

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

  • runtime中的消息转发

    一直以来,都知道object-c是支持消息转发的,也就是说它可以使一个类响应另外一个类中实现的消息(方法)。到底具...

  • runtime中的消息转发

    1动态方法解析 如果一个对象调用了在这个类中方法列表中找不到选择子(SEL),这个时候可以使用为这个选择子添加一个...

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

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

  • runtime底层实现原理

    一、Runtime介绍二、Runtime源码初探三、Runtime消息传递四、Runtime消息转发五、Runti...

  • Runtime

    Runtime的特性主要是消息(方法)的传递,如果消息(方法)在对象中找不到,就会进行转发。 Runtime的介绍...

  • 2022-04-12

    RunTime基础详解 Runtime的特性主要是消息(方法)传递,如果消息(方法)在对象中找不到,就进行转发,具...

  • Runtime-原理

    runtime初探对象与方法的本质runtime-消息发送runtime-动态方法解析runtime-消息转发 r...

  • runtime 消息转发

    实例方法的消息传递:消息的转发建立在objc_msgSend(id, SEL, ...)来实现的。首先会在类对象的...

  • Runtime 消息转发

    目录 消息转发背景知识 消息转发使用方式 消息转发常见问题 消息转发背景知识 1.消息转发的定义Objective...

网友评论

      本文标题:runtime中的消息转发

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