第三篇 Runtime消息转发

本文探讨了Objective-C中消息转发的过程,包括动态方法解析、备用接收者和完整消息转发三个阶段。通过这些机制,开发者可以在运行时处理未定义的方法,避免程序因找不到方法而导致的崩溃。动态方法解析允许添加函数实现,备用接收者提供了将消息转发给其他对象的可能性,而完整消息转发则是最后的解决手段,涉及获取函数的参数和返回值类型,防止程序异常终止。
摘要由CSDN通过智能技术生成

发送消息时会在对应的类对象中搜索方法列表,如果找不到则会沿着继承树向上一直搜索知道继承树根部(通常为NSObject),如果还是找不到并且消息转发都失败了就回执行doesNotRecognizeSelector:方法报unrecognized selector错。

消息转发到底是什么呢?接下来将会逐一介绍最后的三次机会。
1、动态方法解析
2、备用接收者
3、完整消息转发

动态方法解析
首先,Objective-C运行时会调用+resolveInstanceMethod:或者+resolveClassMethod:,让你有机会提供一个函数实现。
如果你添加了函数并返回YES, 那运行时系统就会重新启动一次消息发送的过程。

备用接收者
如果目标对象实现了-forwardingTargetForSelector:,Runtime 这时就会调用这个方法,给你把这个消息转发给其他对象的机会。

完整消息转发
如果在上一步还不能处理未知消息,则唯一能做的就是启用完整的消息转发机制了。
首先它会发送-methodSignatureForSelector:消息获得函数的参数和返回值类型。
如果-methodSignatureForSelector:返回nil,Runtime则会发出-doesNotRecognizeSelector:消息,程序这时也就挂掉了。如果返回了一个函数签名,Runtime就会创建一个NSInvocation对象并发送-forwardInvocation:消息给目标对象。

签名参数"v@:"

示例:执行某个没有实现的方法时,会抛出异常并造成crash,但使用runtime运行时特性进行动态方法解析,或使用备用接收者,或进行完整的消息转发后,则可以很好的避免crash问题。

crash时的源码

#import "ViewController.h"
#import <objc/runtime.h>
#import <objc/message.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.title = @"runtime";

    // 执行work函数,但work函数没有实现
    [self performSelector:@selector(work:)];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

执行结果,抛出异常,造成crash

2018-07-05 18:41:18.160643+0800 DemoRuntime[9374:632785] -[ViewController work:]: unrecognized selector sent to instance 0x7f917a610f50
2018-07-05 18:41:18.209071+0800 DemoRuntime[9374:632785] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController work:]: unrecognized selector sent to instance 0x7f917a610f50'
*** First throw call stack:
(
 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

番薯大佬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值