Objective-C的“多继承”——消息转发

当单继承不够用,很难为问题域建模时,我们通常都会直接想到多继承。多继承是从多余一个直接基类派生类的能力,可以更加直接地为应用程序建模。但是Objective-C不支持多继承,由于消息机制名字查找发生在运行时而非编译时,很难解决多个基类可能导致的二义性问题。

不过其实 Objective-C 也无需支持多继承,我们可以找到如下几种间接实现多继承目的的方法:

  • 消息转发
  • delegate和protocol
  • 类别

消息转发

当向someObject发送某消息,但runtime system在当前类和父类中都找不到对应方法的实现时,runtime system并不会立即报错使程序崩溃,而是依次执行下列步骤:

分别简述一下流程:

1.动态方法解析 向当前类发送 resolveInstanceMethod: 信号,检查是否动态向该类添加了方法。(迷茫请搜索:@dynamic)

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

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

顾名思义,我们可以利用上述过程中的2、3两种方式来完成消息转发。

快速消息转发

快速消息转发的实现方法很简单,只需要重写

- (id)forwardingTargetForSelector:(SEL)aSelector

举个栗子

//Teacher类需要实现将消息转发给Doctor:
- (id)forwardingTargetForSelector:(SEL)aSelector
{
Doctor *doctor = [[Doctor alloc]init];
if ([doctor respondsToSelector:aSelector]) {
return doctor;
}
return nil;
}

标准消息转发

标准消息转发需要重写

methodSignatureForSelector:
forwardInvocation:

举个栗子

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
if (signature==nil) {
signature = [someObj methodSignatureForSelector:aSelector];
}
NSUInteger argCount = [signature numberOfArguments];
for (NSInteger i=0 ; i<argCount ; i++) {
} return signature;
} - (void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL seletor = [anInvocation selector];
if ([someObj respondsToSelector:seletor]) {
[anInvocation invokeWithTarget:someObj];
} }

两种消息转发方式的比较

  • 快速消息转发:简单、快速、但仅能转发给一个对象
  • 标准消息转发:稍复杂、较慢、但转发操作实现可控,可以实现多对象转发

Objective-C的“多继承”——消息转发的更多相关文章

  1. iOS开发·runtime原理与实践: 消息转发篇(Message Forwarding) (消息机制,方法未实现+API不兼容奔溃,模拟多继承)...

    本文Demo传送门: MessageForwardingDemo 摘要:编程,只了解原理不行,必须实战才能知道应用场景.本系列尝试阐述runtime相关理论的同时介绍一些实战场景,而本文则是本系列的消 ...

  2. objc_msgSend消息传递学习笔记 – 消息转发

    该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文. 消息转发机制(message forwarding) Objective-C 在调用对 ...

  3. ios NSMethodSignature and NSInvocation 消息转发

    1.首先获取消息转发时连个函数内部具体内容 MARK:这里是拿[@"xxxxx" length]调用拿来举例说明 (lldb) po signature <NSMethodS ...

  4. netty实现消息转发服务

    1.结构图 2.消息服务器 消息服务器(SNS)由Http Netty Server(HNS)和WebSocket Netty Server(WNS)组成.HNS采用Netty Http+XML协议栈 ...

  5. SmartRoute之大规模消息转发集群实现

    消息转发的应用场景在现实中的应用非常普遍,我们常用的IM工具也是其中之一:现有很多云平台也提供了这种基础服务,可以让APP更容易集成相关功能而不必投入相应的开发成本.对于实现这样一个简单功能并不复杂, ...

  6. iOS的消息转发机制详解

    iOS开发过程中,有一类的错误会经常遇到,就是找不到所调用的方法,当然这类问题比较好解决,给当前对象或其父类对象添加该方法即可,使得编译器在编译时能正确找到该方法:或者,还有另外的方法,由于Objec ...

  7. swizzle method 和消息转发机制的实际使用

    我的工程结构,如图 1-0 图  1-0 在看具体实现以前,先捋以下 实现思路. ViewController 中有一个-(void)Amethod;A方法. -(void)Amethod{ NSLo ...

  8. iOS Runtime的消息转发机制

    前面我们已经讲解Runtime的基本概念和基本使用,如果大家对Runtime机制不是很了解,可以先看一下以前的博客,会对理解这篇博客有所帮助!!! Runtime基本概念:https://www.cn ...

  9. Runtime-消息发送和消息转发

    消息发送 消息发送举例:下面这个OC代码 [person read:book]; 会被编译成: objc_msgSend(person, @selector(read:), book); objc_m ...

随机推荐

  1. easyui问题小结

    http://blog.sina.com.cn/s/blog_77cb836301017lrd.html

  2. iOS——Quartz2D

    0. 复习. 1.基本图形绘制 * 线段(线宽.线段样式) * 矩形(空心.实心.颜色) * 三角形.四边形等形状 1> 说明 - (void)drawRect:(CGRect)rect 什么时 ...

  3. 自我分析-Spring IOC

    Spring IOC容器实现原理大致是容器(Map)+反射(Java反射和cglib).Spring提供丰富的ApplicationContext.以FileSystemXmlApplicationC ...

  4. http 请求报文和响应报文

    1.请求报文 示例: 2.响应报文 示例:

  5. Hystrix的一个坑,queue中的run方法没有被执行?

    今天学的时候随手测了一下Hystrix的queue的异步执行,发现执行queue之后,还没有打印run方法中的内容,程序就结束了: import com.netflix.hystrix.Hystrix ...

  6. MySQL存储过程中的3种循环【转载】

    在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环.还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体 ...

  7. 转:基于 linux 平台的 libpcap 源代码分析

    libpcap 是 unix/linux 平台下的网络数据包捕获函数包,大多数网络监控软件都以它为基础.Libpcap 可以在绝大多数类 unix 平台下工作,本文分析了 libpcap 在 linu ...

  8. Python websocket

    一.自己实现websocket 网上流传的都是Python2的websocket实现 # coding=utf8 # !/usr/bin/python import struct, socket im ...

  9. Python接通图灵机器人

    图灵机器人 图灵机器人特别low,问答水平并不高. import requests print("你好,我是图灵机器人") while 1: s = input() resp = ...

  10. Java JDBC数据库编程

    课程  Java面向对象程序设计 一.实验目的 掌握数据库编程技术 二.实验环境 1.微型计算机一台 2.WINDOWS操作系统,Java SDK,Eclipse开发环境,Microsoft SQL  ...