美文网首页
iOS消息转发机制

iOS消息转发机制

作者: 心猿意码_ | 来源:发表于2022-05-24 14:47 被阅读0次
消息转发机制:

消息转发机制是相对于消息传递机制而言的。

1、消息(传递)机制

RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。

对于C语言,函数的调用在编译的时候会决定调用哪个函数。编译完成之后直接顺序执行,无任何二义性。OC的函数调用称为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(也就是说,在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。

[obj makeText];

首先,编译器将代码[obj makeText];转化为objc_msgSend(obj, @selector (makeText));,在objc_msgSend函数中。首先通过objisa指针找到obj对应的class。在Class中先去cache中 通过SEL查找对应函数method,若 cache中未找到。再去methodList中查找,若methodlist中未找到,则取superClass中查找。若能找到,则将method加入到cache中,以方便下次查找,并通过method中的函数指针跳转到对应的函数中去执行。

2、消息转发机制(可以间接实现多重继承)

消息转发.jpeg
当向someObject发送某消息,但runtime在当前类和父类中都找不到对应方法的实现时,runtime并不会立即报错使程序崩溃,而是依次执行下列步骤:
  • 动态方法解析:向当前类发送resolveInstanceMethod:信号,检查是否动态向该类添加了方法。(迷茫请搜索:@dynamic)

  • 快速消息转发:检查该类是否实现了forwardingTargetForSelector:方法,若实现了则调用这个方法。若该方法返回值对象非nil或非self,则向该返回对象重新发送消息。

  • 标准消息转发:runtime发送methodSignatureForSelector消息获取Selector对应的方法签名。返回值非空则通过forwardInvocation:转发消息,返回值为空则向当前对象发送doesNotRecognizeSelector:消息,程序崩溃退出。

这样如果本类中没有的方法,就会去class中尝试查找,如果有,则返回class对象,让其执行,这样就实现了快速消息转发

第一个阶段,动态方法解析


#import "ViewController.h"
#import "objc/runtime.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self performSelector:@selector(foo:)];
}

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

void fooMethod(id obj, SEL _cmd){
    NSLog(@"Doing foo");
}

第二个阶段,快速消息转发:


#import "ViewController.h"
#import "objc/runtime.h"

@interface Person : NSObject

@end

@implementation Person

- (void)foo{
    NSLog(@"Doing foo");
}

@end

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self performSelector:@selector(foo)];
}

+ (BOOL)resolveInstanceMethod:(SEL)sel{
    return YES;// 返回YES进入下一步转发
}

- (id)forwardingTargetForSelector:(SEL)aSelector{
    if (aSelector == @selector(foo)) {
        return [Person new]; // 返回Person对象,让Person对象接受这个消息
    }
    return [super forwardingTargetForSelector:aSelector];
}

@end

第三个阶段:标准消息转发


#import "ViewController.h"
#import "objc/runtime.h"

@interface Person : NSObject

@end

@implementation Person

- (void)foo{
    NSLog(@"Doing foo");
}

@end

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self performSelector:@selector(foo)];
}

+ (BOOL)resolveInstanceMethod:(SEL)sel{
    return YES;// 返回YES进入下一步转发
}

- (id)forwardingTargetForSelector:(SEL)aSelector{
    return  nil;// 返回nil进入下一步转发
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    if ([NSStringFromSelector(aSelector) isEqualToString:@"foo"]) {
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
    }
    return [super methodSignatureForSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation{
    SEL sel = anInvocation.selector;
    Person *p = [Person new];
    if ([p respondsToSelector:sel]) {
        [anInvocation invokeWithTarget:p];
    }else{
        [self doesNotRecognizeSelector:sel];
    }
}

@end

以上打印结果:Doing foo

相关文章

  • runtime系列文章总结

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

  • iOS理解Objective-C中消息转发机制附Demo

    iOS理解Objective-C中消息转发机制附Demo iOS理解Objective-C中消息转发机制附Demo

  • iOS面试-基础

    [toc] Runloop AutoReleasePool 多线程 响应者链 消息响应机制 消息转发机制 iOS内...

  • iOS 消息转发机制

    今天大概学习了下iOS的消息转发机制,还是挺有收获,在此做下笔记,以便后面温习。 1.iOS的消息转发机制原理如下...

  • iOS面试题总结(二)

    iOS面试题(二) 消息发送和转发机制,SEL和IMP 消息发送转载自黄龙辉消息发送和消息转发机制 在Object...

  • Runtime

    相关简单介绍 消息机制消息传递机制消息转发机制-动态添加方法消息转发机制-快速转发消息转发机制-慢速转发消息转发机...

  • iOS - 消息转发机制

    我们知道,OC是动态语言,所有的方法都会以消息的形式传递给对象,对象会根据方法的类型来进行实例方法或者类方法的选择...

  • 【iOS】消息转发机制

    1、动态方法解析 对象在收到无法处理的消息时,会调用下面的方法,前者是调用类方法时会调用,后者是调用对象方法时会调...

  • iOS消息转发机制

    OC消息转发 oc中的调用对象或者类不存在的方法,会执行一遍消息转发流程.消息转发主要包括4步 首先调用+ (BO...

  • iOS 消息转发机制

    iOS开发过程中我们经常会碰到这样的报错:unrecognized selector sent to instan...

网友评论

      本文标题:iOS消息转发机制

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