iOS中的消息发送和消息转发

消息发送

OC代码
[person read:book];

编译后
objc_msgSend(person, @selector(read:), book);

objc_msgSend的具体流程如下:

  1. 通过isa指针找到所属类
  2. 查找类的cache列表, 如果没有则下一步
  3. 查找类的”方法列表”
  4. 如果能找到与选择子名称相符的方法, 就跳至其实现代码
  5. 找不到, 就沿着继承体系继续向上查找
  6. 如果能找到与选择子名称相符的方法, 就跳至其实现代码
  7. 找不到, 执行”消息转发”

消息转发

上面我们提到, 如果到最后都找不到, 就会来到消息转发,消息转发的流程如下:

  1. 动态方法解析 : 先问接收者所属的类, 你看能不能动态添加个方法来处理这个”未知的消息”? 如果能, 则消息转发结束.
  2. 备用接收者 : 请接收者看看有没有其他对象能处理这条消息? 如果有, 则把消息转给那个对象, 消息转发结束.
  3. 消息签名 : 这里会要求你返回一个消息签名, 如果返回nil, 则消息转发结束.
  4. 完整的消息转发 : 备胎都搞不定了, 那就只能把该消息相关的所有细节都封装到一个NSInvocation对象, 再问接收者一次, 快想办法把这个搞定了. 到了这个地步如果还无法处理, 消息转发机制也无能为力了。
     

1、动态方法解析

对象在收到无法解读的消息后, 首先调用其所属类的这个类方法 :

+ (BOOL)resolveInstanceMethod:(SEL)selector
// selector : 那个未知的选择子
// 返回YES则结束消息转发
// 返回NO则进入备胎

假如尚未实现的方法不是实例方法而是类方法, 则会调用另一个方法resolveClassMethod:

2、备用接收者

动态方法解析失败, 则调用这个方法

- (id)forwardingTargetForSelector:(SEL)selector
// selector : 那个未知的消息
// 返回一个能响应该未知选择子的备胎对象

3、完整的消息转发

消息签名,备用接受者搞不定, 这个方法就准备要被包装成一个NSInvocation对象, 在这里要先返回一个方法签名

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
// NSMethodSignature : 该selector对应的方法签名

给接收者最后一次机会把这个方法处理了, 搞不定就直接程序崩溃!

- (void)forwardInvocation:(NSInvocation *)invocation
// invocation : 封装了与那条尚未处理的消息相关的所有细节的对象

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值