Objective-C中NSInvocation的使用
OC中调用方法某个对象的消息呦两种方式:
#1. performanceSelector: withObject:
#2. NSInvocation.
第一个PerformaceSelector比较常用, 也比较简单。 但是这个方式最多只能传递2个参数
当需要2个以上参数时就只能用NSInvocation了
直接上代码吧, 会注释清楚
- (void)viewDidLoad { [super viewDidLoad]; //用performanceSelector调用三个参数的方法, 但只传递2个参数, 这样方法的第三个参数会自动取我们传的第二个的值
[self performSelector:@selector(printStr1:Str2:Str3:) withObject:@"str1" withObject:@"str2"]; //1.创建方法签名
NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(printStr1:Str2:Str3:)]; //2.根据方法签名来创建NSInvocation对象, 在这之前最好先判断下前面创建的signature是否为nil, 方法不存时就是nil
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; //设置方法的调用者
invocation.target = self;
//设置方法名, 这里一定要跟方法签名类中的方法名一致
invocation.selector = @selector(printStr1:Str2:Str3:); //自定义三个参数
NSString *str1 = @"First argument";
NSString *str2 = @"Second argument";
NSString *str3 = @"Third argument"; //从第二个位置开始添加参数, 因为前面两个位置已经被占用了, 分别时self(target), selector(_cmd)
[invocation setArgument:&str1 atIndex:];
[invocation setArgument:&str2 atIndex:];
[invocation setArgument:&str3 atIndex:]; //3.调用invoke方法
[invocation invoke]; } - (void)printStr1:(NSString *)str1 Str2:(NSString *)str2 Str3:(NSString *)str3 { NSLog(@"%@", str1);
NSLog(@"%@", str2);
NSLog(@"%@", str3);
} @end
输出结果为:
-- ::07.398 BezierPathDemo[:] str1
-- ::07.398 BezierPathDemo[:] str2
-- ::07.399 BezierPathDemo[:] str2
-- ::07.399 BezierPathDemo[:] First argument
-- ::07.399 BezierPathDemo[:] Second argument
-- ::07.399 BezierPathDemo[:] Third argument
NSInvocation使用时有下面三个地方要注意下
1、如果调用的方法不存在
//此时我们应该判断方法是否存在,如果不存在这抛出异常
if (signature == nil) {
//aSelector为传进来的方法
NSString *info = [NSString stringWithFormat:@"%@方法找不到", NSStringFromSelector(aSelector)];
[NSException raise:@"方法调用出现异常" format:info, nil];
}
2、方法的参数个数与外界传进来的参数数组元素个数不符
//此处不能通过遍历参数数组来设置参数,因为外界传进来的参数个数是不可控的
//因此通过numberOfArguments方法获取的参数个数,是包含self和_cmd的,然后比较方法需要的参数和外界传进来的参数个数,并且取它们之间的最小值
NSUInteger argsCount = signature.numberOfArguments - 2;
NSUInteger arrCount = objects.count;
NSUInteger count = MIN(argsCount, arrCount);
for (int i = 0; i < count; i++) {
id obj = objects[i];
// 判断需要设置的参数是否是NSNull, 如果是就设置为nil
if ([obj isKindOfClass:[NSNull class]]) {
obj = nil;
}
[invocation setArgument:&obj atIndex:i + 2];
}
3、判断当前调用的方法是否有返回值
//方法一:
id res = nil;
if (signature.methodReturnLength != 0) {//有返回值
//将返回值赋值给res
[invocation getReturnValue:&res];
}
return res;
//方法二:
//可以通过signature.methodReturnType获得返回的类型编码,因此可以推断返回值的具体类型
Objective-C中NSInvocation的使用的更多相关文章
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- objective C中的字符串NSStirng常用操作
objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的 ...
- Objective C中的ARC的修饰符的使用---- 学习笔记九
#import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ...
- Objective - C中属性和点语法的使用
一.属性 属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性 ...
- Objective C中数组排序几种情况的总结
总结OC中数组排序3种方法:sortedArrayUsingSelector:;sortedArrayUsingComparator:;sortedArrayUsingDescriptors: 数组排 ...
- Objective C中nil/Nil/NULL的区别
nil:指向oc中对象的空指针 Nil:指向oc中类的空指针 NULL:指向其他类型的空指针,如一个c类型的内存指针 NSNull:在集合对象中,表示空值的对象 若obj为nil:[obj messa ...
- objective C中数据持久化方式1--对象归档
第一.数据持久化的方式: NSKeyedArchiver--对象归档 属性列表化(NSArray.NSDictionary.NSUserDefault) SQlite数据库.CoreData数据库 其 ...
- Objective - C 中NSString (字符串)与C中的字符串转换问题
NSString是一个常用的类,NSString是原生支持unicode C中的字符串 比如char * a = "hello world"; 是utf8类型的, char* d ...
随机推荐
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- SQL Server 致程序员(容易忽略的错误)
标签:SQL SERVER/MSSQL/DBA/T-SQL好习惯/数据库/需要注意的地方/程序员/容易犯的错误/遇到的问题 概述 因为每天需要审核程序员发布的SQL语句,所以收集了一些程序员的一些常见 ...
- Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用
OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...
- java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出
上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...
- SQLSERVER聚集索引与非聚集索引的再次研究(上)
SQLSERVER聚集索引与非聚集索引的再次研究(上) 上篇主要说聚集索引 下篇的地址:SQLSERVER聚集索引与非聚集索引的再次研究(下) 由于本人还是SQLSERVER菜鸟一枚,加上一些实验的逻 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- C# 正则表达式大全
文章导读 正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串.正则表达式无疑是处理文本最有力的工具,而.NET提供的Regex类实现了验证正则表达式的方法.Regex 类表示不可变(只读)的 ...
- Android 在Android代码中执行命令行
1.路径最好不要是自己拼写的路径/mnt/shell/emulated/0/wifidog.conf 最好是通过方法获取的路径,不然可能导致命令无效 (挂载点的原因) public static f ...
- Linux网卡驱动安装、防火墙原理
安装网卡驱动程序: 需要检查是否安装kernel依赖包: rpm –q kernel-devel #检查kernel依赖包是否安装 yum –y install kernel-devel 检查gcc和 ...
- 浅谈单片机中C语言与汇编语言的转换
做了一单片机设计,要用C语言与汇编语言同时实现,现将这次设计的感受和收获,还有遇到的问题写下,欢迎感兴趣的朋友交流想法,提出建议. 单片机设计:基于51单片机的99码表设计 软件环境:Proteus8 ...