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的更多相关文章

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

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

  2. 【引】runtime全解析,P1:Programming Guide

    h2.Overview Objective-C language defers as many decisions as it can from compile time and link time ...

  3. Objective-C Runtime

    原文地址:http://tech.glowing.com/cn/objective-c-runtime/ 原作者:顾鹏 如有侵权,请联系本人删除 Objective-C Objective-C 扩展了 ...

  4. iOS运行时Runtime浅析

    运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...

  5. Effective Objective-C 2.0 — 第12条:理解消息转发机制

    11 条讲解了对象的消息传递机制 12条讲解对象在收到无法解读的消息之后会发生什么,就会启动“消息转发”(message forwarding)机制, 若对象无法响应某个选择子,则进入消息转发流程. ...

  6. iOS开发——高级篇——Objective-C特性:Runtime

    Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和转发.下面通过分析Apple开源的 ...

  7. 李洪强iOS经典面试题上

    李洪强iOS经典面试题上     1. 风格纠错题 修改完的代码: 修改方法有很多种,现给出一种做示例: // .h文件 // http://weibo.com/luohanchenyilong/ / ...

  8. 详解Objective-C runtime

    感谢翻译小组成员wingpan热心翻译.本篇文章是我们每周推荐优秀国外的技术类文章的其中一篇.如果您有不错的原创或译文,欢迎提交给我们,更欢迎其他朋友加入我们的翻译小组(联系qq:2408167315 ...

  9. 招聘一个靠谱的ios

    1. 风格纠错题 修改方法有很多种,现给出一种做示例: 最终改为: 下面对具体修改的地方, 2. 什么情况使用 weak 关键字,相比 assign 有什么不同? 什么情况使用 weak 关键字? 1 ...

随机推荐

  1. JAVA反射技术的使用

    前言 在开发html使用jquery提交post的时候,可以使用jquery遍历from元素里面的input元素实现参数组合,这样就不用手动打参数了,特别是在参数很多的时候,费神费时. 我开发Andr ...

  2. OpenStack(0) - Table of Contents

    1. Keystone OpenStack Identity Service2. Starting OpenStack Image Service3. Starting OpenStack Compu ...

  3. 转:整理一下Entity Framework的查询

    Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...

  4. Phpstorm Xdebug Web程序调试

    平时调试php程序的时候,可以通过在代码中添加var_dump等函数来实现简单的断点调试. 下面介绍另一种方法,通过Phpstorm和Xdebug来进行调试. 1.下载Xdebug 这个是官网下载地址 ...

  5. 详解Android动画之Frame Animation(转)

    在开始实例讲解之前,先引用官方文档中的一段话: Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画.Frame动画可以被定义在XML文件中,也可以完全编码实现. ...

  6. DelegatingFilterProxy

    安全过滤器链 Spring Security的web架构是完全基于标准的servlet过滤器的. 它没有在内部使用servlet或任何其他基于servlet的框架(比如spring mvc), 所以它 ...

  7. HDU Sky数 2097

    解题思路:类比求出10进制数各个位上的数字之和,求出12进制和16进制上的数. #include<cstdio> #include<cstring> #include<a ...

  8. SSH思路

    hibernate的配置写到spring的配置中,用spring管理和调用hibernate的工厂和session等.struts的话,通常有2中.一种是用spring中的一个工厂类代替struts的 ...

  9. 深入学习Heritrix---解析CrawlController(转)

    当我们以Web UI方式使用Heritrix时,点击任务开始(start)按钮时,Heritrix就开始了它的爬取工作.但它的内部 执行流程是怎样的呢?别急,下面将慢慢道来. (一)CrawlJobH ...

  10. 纠结的ARC

    xcode不断进步,在xcode4中引入了ARC的概念.您用或者不用它就在那里,于是有了本文:如何在未使用arc的工程中引入一个使用了arc特性的文件,如何在arc工程中引用未使用arc的文件.其实说 ...