Message Forwarding
【Preprocess】
在使用forwarding机制前,会先经历2个步骤,只有当这2个步骤均失败的情况下,才会激活forwarding。
1、+(BOOL)resolveInstanceMethod:(SEL)selector、resolveClassMethod。
当第一次没找到SEL时,调用上述两方法之一。如果在上述2方法中加入了方法,并返回YES,则会尝试重新解析此SEL。

2、-(id)forwardingTargetForSelector:(SEL)selector,当上述第1条机制失败后,本条机制会被激活。此方法返回能够处理SEL的对象。如果返回非nil,则会调用此对象的SEL。此种机制无法定制参数。
当上述2个机制均失败后,会起用forwarding机制,如下。

【Message Forwarding】
If you send a message to an object that does not handle that message, before announcing an error the runtime sends the object a forwardInvocation: message with an NSInvocation object as its sole argument—the NSInvocation object encapsulates the original message and the arguments that were passed with it.
forwardInvocation方法可以帮助我们轻松的实现完美转发。
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([someOtherObject respondsToSelector:
[anInvocation selector]])
[anInvocation invokeWithTarget:someOtherObject];
else
[super forwardInvocation:anInvocation];
}
forwarding实际上提供了一种多生继承的变相实现。返回值被存储在NSInvocation中,NSObject框架会把NSInvocation中的返回值返回给原调用者。

Although forwarding mimics inheritance, the NSObject class never confuses the two. Methods like respondsToSelector: and isKindOfClass: look only at the inheritance hierarchy, never at the forwarding chain. If, for example, a Warrior object is asked whether it responds to a negotiate message,
if ( [aWarrior respondsToSelector:@selector(negotiate)] )
...
the answer is NO, even though it can receive negotiate messages without error and respond to them.
如果想让respondsToSelector对代理的方法也返回YES,可以按如下实现:
- (BOOL)respondsToSelector:(SEL)aSelector
{
if ( [super respondsToSelector:aSelector] )
return YES;
else {
/* Here, test whether the aSelector message can *
* be forwarded to another object and whether that *
* object can respond to it. Return YES if it can. */
}
return NO;
}
if an object forwards any remote messages it receives, it should have a version of methodSignatureForSelector: that can return accurate descriptions of the methods that ultimately respond to the forwarded messages
- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [surrogate methodSignatureForSelector:selector];
}
return signature;
}
Message Forwarding的更多相关文章
- iOS开发·runtime原理与实践: 消息转发篇(Message Forwarding) (消息机制,方法未实现+API不兼容奔溃,模拟多继承)...
本文Demo传送门: MessageForwardingDemo 摘要:编程,只了解原理不行,必须实战才能知道应用场景.本系列尝试阐述runtime相关理论的同时介绍一些实战场景,而本文则是本系列的消 ...
- 【引】runtime全解析,P1:Programming Guide
h2.Overview Objective-C language defers as many decisions as it can from compile time and link time ...
- Objective-C Runtime
原文地址:http://tech.glowing.com/cn/objective-c-runtime/ 原作者:顾鹏 如有侵权,请联系本人删除 Objective-C Objective-C 扩展了 ...
- iOS运行时Runtime浅析
运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...
- Effective Objective-C 2.0 — 第12条:理解消息转发机制
11 条讲解了对象的消息传递机制 12条讲解对象在收到无法解读的消息之后会发生什么,就会启动“消息转发”(message forwarding)机制, 若对象无法响应某个选择子,则进入消息转发流程. ...
- iOS开发——高级篇——Objective-C特性:Runtime
Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和转发.下面通过分析Apple开源的 ...
- 李洪强iOS经典面试题上
李洪强iOS经典面试题上 1. 风格纠错题 修改完的代码: 修改方法有很多种,现给出一种做示例: // .h文件 // http://weibo.com/luohanchenyilong/ / ...
- 详解Objective-C runtime
感谢翻译小组成员wingpan热心翻译.本篇文章是我们每周推荐优秀国外的技术类文章的其中一篇.如果您有不错的原创或译文,欢迎提交给我们,更欢迎其他朋友加入我们的翻译小组(联系qq:2408167315 ...
- 招聘一个靠谱的ios
1. 风格纠错题 修改方法有很多种,现给出一种做示例: 最终改为: 下面对具体修改的地方, 2. 什么情况使用 weak 关键字,相比 assign 有什么不同? 什么情况使用 weak 关键字? 1 ...
随机推荐
- poj 2192 (DP)
这个题题目意思是给你三个字符串str1,str2,str3.将str3从左自右扫描,去匹配str1和str2中的元素,不可重复,若存在一种匹配方法使得str1和str2都被匹配完全了,则输出yes,否 ...
- [转]微软联合CSDN英雄在线编程大赛
2014 新年将至,微软联合CSDN英雄会共同举办本次第三届在线编程大赛,题目详情如下: 有一个字符串"iinbinbing",截取不同位置的字符‘b’.‘i’.‘n’.‘g’组合 ...
- 51nod1364 最大字典序排列
不断的在cur的后面找最大的符合条件的数扔到cur的前面. 用线段树维护操作就可以了. #include<cstdio> #include<cstring> #include& ...
- maven的settings.xml详细说明
转自:http://writeblog.csdn.net/ <?xml version="1.0" encoding="UTF-8"?> <s ...
- aspose调用打印机打印文档
aspose很不错的插件,功能非常强大,用到了其中的aspose.word. 如何生成word文档,点击. 下面说说如何如何通过打印机打印文档. aspose提供了一个print方法,通过该方法可以直 ...
- 一起学CUDA(一)
前提是电脑的显卡支持CUDA,N卡一般是支持的,如果是A卡就没办法了.主要针对Windows环境,Linux和Mac也有相应的安装包.CUDA环境搭建:Step1:安装代码环境VS2010:Step2 ...
- ORACLE 常用SQL查询
一.ORACLE的启动和关闭 1 .在单机环境下 要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a.启动ORACLE系统 oracle > sv ...
- 【NYOJ-35】表达式求值——简单栈练习
表达式求值 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min ...
- 【转】Mac 10.10 yosemite 安装samba替代系统samba组件 -- samba不错不错
原文网址:http://gcell.blog.163.com/blog/static/52666594201501084530277/ 1.首先,在系统偏好设置的共享设置中,关掉局域网文件共享(去掉打 ...
- Nodejs学习之一 下载安装与部署nodejs
1,下载nodejs 访问nodejs官网 www.nodejs.org/download/ 下载与机器相匹配的版本 2,安装nodejs 下载下来的msi包一直点击下一步即可 3,部署环 ...