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

(lldb) po signature
<NSMethodSignature: 0x170076f80>
number of arguments =
frame size =
is special struct return? NO
return value: -------- -------- -------- --------
type encoding (Q) 'Q'
flags {}
modifiers {}
frame {offset = , offset adjust = , size = , size adjust = }
memory {offset = , size = }
argument : -------- -------- -------- --------
type encoding (@) '@'
flags {isObject}
modifiers {}
frame {offset = , offset adjust = , size = , size adjust = }
memory {offset = , size = }
argument : -------- -------- -------- --------
type encoding (:) ':'
flags {}
modifiers {}
frame {offset = , offset adjust = , size = , size adjust = }
memory {offset = , size = }
(lldb) po anInvocation
<NSInvocation: 0x178075d80>
return value: {Q}
target: {@} 0x17801e350
selector: {:} length

apple doc : https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

讲解type encoding具体用法:http://nshipster.com/type-encodings/

2. 具体案例:json解析数据时 NSJSONSerialization 会自动把他们换成 NSNull。当我们再去用dict[@“hello”]的时候,就会出触发exception,导致程序崩溃(ios6会出现)

两种实现:

第一种:
#import "NSNull+OVNatural.h" @implementation NSNull (OVNatural)
- (void)forwardInvocation:(NSInvocation *)invocation
{
if ([self respondsToSelector:[invocation selector]]) {
[invocation invokeWithTarget:self];
}
} - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *sig = [[NSNull class] instanceMethodSignatureForSelector:selector];
if(sig == nil) {
sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
return sig;
} @end
第二种:
#define NSNullObjects @[@"",@0,@{},@[]] @interface NSNull (InternalNullExtention)
@end @implementation NSNull (InternalNullExtention) - (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
for (NSObject *object in NSNullObjects) {
signature = [object methodSignatureForSelector:selector];
if (signature) {
break;
}
} }
return signature;
} - (void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL aSelector = [anInvocation selector]; for (NSObject *object in NSNullObjects) {
if ([object respondsToSelector:aSelector]) {
[anInvocation invokeWithTarget:object];
return;
}
} [self doesNotRecognizeSelector:aSelector];
}
@end
- (void)forwardInvocation:(NSInvocation *)anInvocation  只需改变调用目标,使消息在新目标上得以调用即可。然而这样实现出来的方法与“备援接收者”方案所实现的方法等效,所以很少有人采用这么简单的实现方式。比较有用的实现方式为:在触发消息前,先以某种方式改变消息内容,比如追加另外一个参数。

实现此方法时,若发现某调用操作不应由本类处理,则需调用超类的同名方法。这样的话,继承体系中的每个类都有机会处理此调用请求,直至NSObject。如果最后调用了NSObject类的方法,那么该方法还会继而调用“doesNotRecognizeSelector:”以抛出异常,此异常表明选择子最终未能得到处理。

未完,待续....

ios NSMethodSignature and NSInvocation 消息转发的更多相关文章

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

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

  2. iOS Runtime的消息转发机制

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

  3. iOS 消息转发以及 NSProxy 实战

    最后更新: 2018-01-17 一.消息派发机制-NSObject 在 iOS 开发中, 调用对象的方法就是给对象发送一个消息.了解消息的派发机制对于iOS开发来说是一个很实用且强大的工具, 下面我 ...

  4. iOS消息转发

    消息转发是一种功能强大的技术,可以大大增加Objective-C的表现力.什么是消息转发?简而言之,它允许未知的消息被困住并作出反应.换句话说,无论何时发送未知消息,它​​都会以一个很好的包发送到您的 ...

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

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

  6. iOS - 消息转发处理

    详细运行时基础 NSInvocation介绍 NSHipster-Swizzling Objective-C Method相关方法分析 Type Encodings Objc是OOP,所以有多态. 当 ...

  7. iOS 消息转发机制

    这篇博客的前置知识点是 OC 的消息传递机制,如果你对此还不了解,请先学习之,再来看这篇.这篇博客我尝试用口语的方式像讲述 PPT 一样给大家讲述这个知识点. 我们来思考一个问题,如果对象在收到无法解 ...

  8. iOS 消息转发

    消息转发   delegate和protocol   类别      消息转发   当向someObject发送某消息,但runtime system在当前类和父类中都找不到对应方法的实现时,runt ...

  9. iOS开发-消息转发

    消息转发是OC运行时比较重要的特性,Objective-C运行时的主要的任务是负责消息分发,我们在开发中"unrecognized selector sent to instance xx& ...

随机推荐

  1. Asp.net MVC中的ViewData与ViewBag

    Asp.net MVC中的ViewData与ViewBag 在Asp.net MVC 3 web应用程序中,我们会用到ViewData与ViewBag,对比一下: ViewData ViewBag 它 ...

  2. 谈谈以下关键字的作用auto static register const volatile extern

    (1)auto 这个这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量.这个关键字不怎么多写,因为所有的变量默认就是 ...

  3. [九度OJ]1008.最短路径问题

    原题链接:http://ac.jobdu.com/problem.php?pid=1008 题目描述: 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离 ...

  4. bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1818  Solved: 761[Submit][Status ...

  5. JUnit学习总结

    Junit简介: Junit最初是由Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),为单元测试(Unit Test) ...

  6. C语言结构

    一个进程在内存中的布局如图所示:        .text段(正文段)——保存程序所执行的程序二进制文件,CPU执行的机器指令部分:一个程序只有一个副本:只读,防止程序由于意外事故而修改自身指令. . ...

  7. 利用ACE 自己实现的线程池

    1: 线程池组件的配置文件: [log] ;DEBUG = 0 ;INFO = 1 ;WARN = 2 ;FAULT = 3 level=0 ;SCREENOUT = 0 ;FILEOUT = 1 ; ...

  8. sqlplus 连接数据库报错SP2-0642: SQL*Plus internal error state 2130, context 0:0:0

    sqlplus 连接数据库报错SP2-0642: SQL*Plus internal error state 2130, context 0:0:0 问题描述: 使用sqlplus客户端登录数据库,报 ...

  9. flot图插件使用

    <div id="budget-charts"></div> <script src="../../../plugins/ace/js/fl ...

  10. sql语句相关整理

    select * from jcls_lawfirms where length(lf_2)=2 for updateselect * from jcls_lawfirms where length( ...