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. Ruby应用记录:修改文件中某个字符串

    #修改android客户端中服务器地址的默认值为对应环境的服务器地址 #!/usr/bin/ruby ostr="192.168.88.95:8088" nstr="19 ...

  2. 常见shell操作

    一.find命令详细 find命令 -- 之查找指定时间内修改过的文件 比如我们要查找linux下指定时间内做过改动的文件,我们可以用find命令,其实find命令的功能十分强大,下面我们通过几个简单 ...

  3. 关于Spring的Controller及Struts的Action的多线程的注意

    struts是线程安全,并不是指多线程,而是指单态,当多个用户访问一个请求的时候,服务器内存中只有一个与之对应的action类对象,execute方法加上了同步关键字,如果你在action里加上一个全 ...

  4. c#文件转化byte数组

    public static byte[] ReadFile(string fileName) { if (!File.Exists(fileName)) { throw new Exception(& ...

  5. java 小结2 多态问题和容器介绍

    面向对象这个东西,其实我们一直是不是都没有感觉到自己在用,以后我一定要用用.以前学c#时候认真的看过一次,最近一直研究java.随便再看看. 多态问题: 在java中多态分为(1)编译时多态和(2)运 ...

  6. HW5.4

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  7. HW1.1

    public class Solution { public static void main(String[] args) { System.out.println("Welcome to ...

  8. Java 线程池架构原理和源码解析(ThreadPoolExecutor)

    在前面介绍JUC的文章中,提到了关于线程池Execotors的创建介绍,在文章:<java之JUC系列-外部Tools>中第一部分有详细的说明,请参阅: 文章中其实说明了外部的使用方式,但 ...

  9. 开始使用storm

     开始使用storm 本章将讲述如何安装.部署.启动和停止 Storm 集群. Storm 的安装比较简单,但在安装 Storm 之前需要做好充足的准备,本章将介绍安装的整个流程.在官网上可以下载到S ...

  10. 【Hibernate】--一对一关联、联合主键

    一.数据模型 1.学生信息模型(编号.名称.身份信息) public class Student implements java.io.Serializable{ private static fin ...