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 ...
随机推荐
- 【Todo】所有Locked的题目的分析解答
下面这个链接有比较全的leetcode题目包括锁的 http://www.cnblogs.com/grandyang/p/4606334.html https://leetcode.com/probl ...
- LA 4670 (AC自动机 模板题) Dominating Patterns
AC自动机大名叫Aho-Corasick Automata,不知道的还以为是能自动AC的呢,虽然它确实能帮你AC一些题目.=_=|| AC自动机看了好几天了,作用就是多个模式串在文本串上的匹配. 因为 ...
- 点滴积累【SQL Server】---SQL语句操作约束
说明: --主键约束(Primary Key constraint):要求主键列的数据唯一,并且不允许为空. --唯一约束(Unique Constraint):要求该列唯一,允许为空,但只能出现一个 ...
- Linux diff patch
/***************************************************************************** * Linux diff patch * ...
- LeetCode Binary Tree Maximum Path Sum 二叉树最大路径和(DFS)
题意:给一棵二叉树,要求找出任意两个节点(也可以只是一个点)的最大路径和,至少1个节点,返回路径和.(点权有负的.) 思路:DFS解决,返回值是,经过从某后代节点上来到当前节点且路径和最大的值.要注意 ...
- mysql三
修改字段名 mysql> alter table users change id user_id INT UNSIGNED AUTO_INCREMENT; 修改字段类型 mysql> al ...
- (转)CWnd与HWND的区别与转换
一.区别HWND是句柄,CWnd是MFC窗体类,CWnd中包含HWND句柄成员对象是m_hWnd.HWND是Windows系统中对所有窗口的一种标识,即窗口句柄.这是一个SDK概念. CWnd是M ...
- ecshop文章详情页显示浏览数
1.后台执行以下SQL语句 ) NOT NULL 2.找到article.php的这段代码 else { $smarty->display('article_pro.dwt', $cache_i ...
- POJ 1942 Paths on a Grid
// n*m 的格子 从左下角走到右上角的种数// 相当于从 n+m 的步数中选 m 步往上走// C(n+m,m) #include <iostream> #include <st ...
- dynamic_cast
作为四个内部类型转换操作符之一的dynamic_cast和传统的C风格的强制类型转换有着巨大的差别.除了dynamic_cast以外的转换,其行为的都是在编译期就得以确定的,转换是否成功,并不依赖被转 ...