runtime从入门到精通(五)—— 消息发送和消息转发
来源:互联网 发布:牛奶推荐 知乎 编辑:程序博客网 时间:2024/05/18 00:31
前一篇文章中,我们介绍了runtime相关的术语的数据结构,查看链接:runtime相关的术语的数据结构。本文主要讲解与runtime相关的消息发送和消息转发两个重要模块。
消息发送
消息发送举例:下面这个OC代码
[person read:book];
会被编译成:
objc_msgSend(person, @selector(read:), book);
objc_msgSend的具体流程如下:
- 通过isa指针找到所属类
- 查找类的cache列表, 如果没有则下一步
- 查找类的”方法列表”
- 如果能找到与选择子名称相符的方法, 就跳至其实现代码
- 找不到, 就沿着继承体系继续向上查找
- 如果能找到与选择子名称相符的方法, 就跳至其实现代码
- 找不到, 执行”消息转发”.
消息转发
上面我们提到, 如果到最后都找不到, 就会来到消息转发,消息转发的流程如下:
- 动态方法解析 : 先问接收者所属的类, 你看能不能动态添加个方法来处理这个”未知的消息”? 如果能, 则消息转发结束.
- 备胎(后备接收者) : 请接收者看看有没有其他对象能处理这条消息? 如果有, 则把消息转给那个对象, 消息转发结束.
- 消息签名 : 这里会要求你返回一个消息签名, 如果返回nil, 则消息转发结束.
- 完整的消息转发 : 备胎都搞不定了, 那就只能把该消息相关的所有细节都封装到一个NSInvocation对象, 再问接收者一次, 快想办法把这个搞定了. 到了这个地步如果还无法处理, 消息转发机制也无能为力了。
1. 动态方法解析
对象在收到无法解读的消息后, 首先调用其所属类的这个类方法 :
+ (BOOL)resolveInstanceMethod:(SEL)selector// selector : 那个未知的选择子// 返回YES则结束消息转发// 返回NO则进入备胎
假如尚未实现的方法不是实例方法而是类方法, 则会调用另一个方法resolveClassMethod:
2. 备胎
动态方法解析失败, 则调用这个方法
- (id)forwardingTargetForSelector:(SEL)selector// selector : 那个未知的消息// 返回一个能响应该未知选择子的备胎对象
通过备胎这个方法, 可以用”组合”来模拟出”多重继承”.
3. 消息签名
备胎搞不定, 这个方法就准备要被包装成一个NSInvocation对象, 在这里要先返回一个方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector// NSMethodSignature : 该selector对应的方法签名
4. 完整的消息转发
给接收者最后一次机会把这个方法处理了, 搞不定就直接程序崩溃!
- (void)forwardInvocation:(NSInvocation *)invocation// invocation : 封装了与那条尚未处理的消息相关的所有细节的对象
在这里能做的比较现实的事就是 : 在触发消息前, 先以某种方式改变消息内容, 比如追加另外一个参数, 或是改变消息等等. 实现此方法时, 如果发现某调用操作不应该由本类处理, 可以调用超类的同名方法. 则继承体系中的每个类都有机会处理该请求, 直到NSObject. 如果NSObject搞不定, 则还会调用doesNotRecognizeSelector:来抛出异常, 此时你就会在控制台看到那熟悉的unrecognized selector sent to instance..
上面这4个方法均是模板方法,开发者可以override,由runtime来调用。最常见的实现消息转发,就是重写方法3和4,忽略这个消息或者代理给其他对象.
哈哈,到这里,有关runtime的理论知识就先告于段落,在下篇文章中,你们要的干货来了—— runtime在实际开发中的应用,跳转链接:点我跳转
1 0
- runtime从入门到精通(五)—— 消息发送和消息转发
- Runtime的入门与应用之五-消息发送与转发
- runtime从入门到精通(一)—— 初识runtime
- runtime从入门到精通(三)—— runtime常用接口方法
- runtime从入门到精通(四)—— 一些runtime相关术语的数据结构
- runtime从入门到精通(六)—— runtime在实际开发中的应用
- runtime从入门到精通(八)—— 使用runtime实现字典转模型
- runtime从入门到精通(一)—— 初识runtime
- runtime从入门到精通(三)—— runtime常用接口方法
- Runtime系列(消息转发)
- 神经病院Objective-C Runtime住院第二天——消息发送与转发
- 神经病院Objective-C Runtime住院第二天——消息发送与转发
- 【WLAN从入门到精通-基础篇】第9期——直接转发和隧道转发
- storm从入门到精通 第三节 storm消息机制
- runtime从入门到精通(二)—— 官方文档翻译
- runtime从入门到精通(七)—— 自动归档和解档
- runtime从入门到精通(九)—— 万能界面跳转
- runtime从入门到精通(二)—— 官方文档翻译
- JAVAweb开发技术-------(三)JSP (封装自己的标签库)
- SharedPreferences存储图片对象与获取
- 从git仓库中下载项目到Studio中
- 求连续子数组的最大和---2017滴滴笔试编程1
- 转:npm 模块安装机制简介
- runtime从入门到精通(五)—— 消息发送和消息转发
- 快速全球索引-百万数据源测试
- ACM新的篇章
- Spark学习(单机本地提交作业)
- PHP-字符串操作
- Android基础:screenOrientation 屏幕方向
- 机器学习常见算法个人总结(面试用)
- JVM学习笔记(三)------内存管理和垃圾回收
- 【bzoj4203】【JZ雅礼联考】同桌的你 题解