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 ...
随机推荐
- Windows2012R2备用域控搭建
Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自己的ip,备dns:备域控的ip备域控的主dns:自己的ip,备dns:主域控的ip 客户端主dns:主域控的ip,备dns: ...
- Web性能优化:图片优化
程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...
- Hawk 4.4 执行器
执行器是负责将Hawk的结果传送到外部环境的工具.你可以写入数据表,数据库,甚至执行某个特定的动作,或是生成文件等等. 在调试模式下,执行器都是不工作的.这是为了避免产生副作用.否则,每刷新一遍数据, ...
- CRL快速开发框架系列教程十二(MongoDB支持)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- AFNetworking 3.0 源码解读(六)之 AFHTTPSessionManager
AFHTTPSessionManager相对来说比较好理解,代码也比较短.但却是我们平时可能使用最多的类. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilit ...
- C++随笔:从Hello World 探秘CoreCLR的内部(1)
紧接着上次的问题,上次的问题其实很简单,就是HelloWorld.exe运行失败,而本文的目的,就是成功调试HelloWorld这个控制台应用程序. 通过我的寻找,其实是一个名为TryRun的文件出了 ...
- 强强联合,Testin云测&云层天咨众测学院开课了!
Testin&云层天咨众测学院开课了! 共享经济时代,测试如何赶上大潮,利用碎片时间给女票或者自己赚点化妆品钱? 2016年12月13日,Testin联手云层天咨带领大家一起推开众测的大门 ...
- .NET平台和C#编程的总结
第一章 简单认识.NET框架 (1)首先我们得知道 .NET框架具有两个主要组件:公共语言进行时CLR(Common Language Runtime)和框架类库FCL(Framework ...
- CSS3 @keyframes 动画
CSS3的@keyframes,它可以取代许多网页动画图像,Flash动画,和JAVAScripts. CSS3的动画属性 下面的表格列出了 @keyframes 规则和所有动画属性: 浏览器支持 表 ...
- Oracle Standard Error 列表
今天,我特意从网上找了一些,以及自己平时总结的,关于错误编号和说明,平时我们在写项目的时候,往往是可能会出现下面这些错误,例如:违反唯一约束,无效的会话ID,等等.希望对大家有点帮助!可以看看,如果有 ...