消息发送

消息发送举例:下面这个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对应的方法签名

4. 完整的消息转发

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

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

在这里能做的比较现实的事就是 : 在触发消息前, 先以某种方式改变消息内容, 比如追加另外一个参数, 或是改变消息等等. 实现此方法时, 如果发现某调用操作不应该由本类处理, 可以调用超类的同名方法. 则继承体系中的每个类都有机会处理该请求, 直到NSObject. 如果NSObject搞不定, 则还会调用doesNotRecognizeSelector:来抛出异常, 此时你就会在控制台看到那熟悉的unrecognized selector sent to instance..

上面这4个方法均是模板方法,开发者可以override,由runtime来调用。最常见的实现消息转发,就是重写方法3和4,忽略这个消息或者代理给其他对象.

Runtime-消息发送和消息转发的更多相关文章

  1. RocketMQ源码 — 三、 Producer消息发送过程

    Producer 消息发送 producer start producer启动过程如下图 public void start(final boolean startFactory) throws MQ ...

  2. 微信小程序发送模板消息

    微信小程序发送模板消息 标签(空格分隔): php 看小程序文档 [模板消息文档总览]:https://developers.weixin.qq.com/miniprogram/dev/framewo ...

  3. RocketMQ 消息发送system busy、broker busy原因分析与解决方案

    目录 1.现象 2.原理解读 2.1 RocketMQ 网络处理机制概述 2.2 pair.getObject1().rejectRequest() 2.3 漫谈transientStorePoolE ...

  4. 【RocketMQ源码学习】- 3. Client 发送同步消息

    本文较长,代码后面给了方法简图,希望给你帮助 发送的方式 同步发送 异步发送 消息的类型 普通消息 顺序消息 事务消息 发送同步消息的时序图 为了防止读者朋友嫌烦,可以看下时序图,后面我也会给出方法的 ...

  5. Orleans 客户端请求的消息流转以及消息在Silo中再路由机制

    1.客户端是一个OutSideRuntimeClient,在这个客户端类中有一个消息代理中心transport(类型为ProxiedMessageCenter) 2.ProxiedMessageCen ...

  6. (二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念

    原文:(二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念 没错我还是没有讲怎么安装和写一个HelloWord,不过快了,这一章我们先了解下RabbitMQ的基本概念. Rabbit ...

  7. iOS 消息发送与转发详解

    Objective-C 是一门动态语言,它将很多静态语言在编译和链接时期做的事情,放到了运行时来处理.之所以能具备这种特性,离不开 Runtime 这个库.Runtime 很好的解决了如何在运行时期找 ...

  8. Runtime - 消息发送原理

    Runtime - 消息发送原理. Objective-C运行时的核心就在于消息分派器objc_msgSend,消息分派器把选择器映射为函数指针,并调用被引用的函数. 要想理解objc_msgSend ...

  9. 理解Objective-C Runtime(三)消息转发机制

    消息转发机制概述 上一篇博客消息传递机制中讲解了Objective-C中对象的「消息传递机制」.本文需要讲解另外一个重要问题:当对象受到无法处理的消息之后会发生什么情况? 显然,若想令类能理解某条消息 ...

随机推荐

  1. [js]jquery里的jsonp实现ajax异源请求

    同源请求-jquery <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/ ...

  2. CentOS 7 下使用yum安装MySQL5.7.20

    CentOS7默认数据库是mariadb, 但是 好多用的都是mysql ,但是CentOS7的yum源中默认好像是没有mysql的. 上一篇安装的是5.6的但是我想安装5.7的  yum安装是最简单 ...

  3. Cocos Creator 加载和切换场景(官方文档摘录)

    Cocos Creator 加载和切换场景(官方文档摘录) 在 Cocos Creator 中,我们使用场景文件名( 可以不包含扩展名)来索引指代场景.并通过以下接口进行加载和切换操作: cc.dir ...

  4. input[type = 'date']标签。

    1.首先调用浏览器自带时间控件,input的type属性有以下几种写法: type=’date’ //显示年.月.日 type=‘month’//显示年.月 type=‘week’//显示年.周 ty ...

  5. windows程序设计 获取系统文件路径

    获取系统文件路径,打印到txt文件中. #include <windows.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hP ...

  6. IP通信基础学习第二周

    此周的课程学习应该算是我对此科目真正学校生涯的开始吧,尽管我对该科目仍感到很陌生. 课程一开头,老师就给我们简单的介绍了网络的定义.发展及其分类,重点讲了网络拓扑结构及其在局域网上具体的分层情况.该部 ...

  7. jquery.autocomplete详解

    语法: autocomplete(urlor data, [options] ) 参数: url or data:数组或者url [options]:可选项,选项解释如下: 1) minChars ( ...

  8. hello2 source anaylis

    首先,我们先来看一看这一段的整体代码, 代码如下: @WebServlet("/greeting") public class GreetingServlet extends Ht ...

  9. 复习-css列表和表格相关属性

    css列表和表格相关属性 list-style:设置所有列表属性 list-style-image:将图像设置为列表项标记,主要有url值 list-style-position:设置列表项标记的放置 ...

  10. Gym - 100989H

    After the data structures exam, students lined up in the cafeteria to have a drink and chat about ho ...