NSInvocation简单用法
来源:互联网 发布:wow60 n服数据库 编辑:程序博客网 时间:2024/06/14 02:39
在 iOS中可以直接调用某个对象的消息方式有两种:
一种是performSelector:withObject 另一种就是NSInvocation
第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那就需要做些额外工作才能搞定。那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作。
1、
DZPerson.h:
#import <Foundation/Foundation.h>@interface DZPerson : NSObject@end
.h文件中并不需要有方法的声明
DZPerson.m
#import "DZPerson.h"@implementation DZPerson- (void) showName:(NSString *) name { NSLog(@"name : %@", name);}- (void) showName:(NSString *) name andAge:(NSUInteger) age { NSLog(@"name : %@, age : %lu", name, (unsigned long)age);}- (NSString *) getAgeAndNameWithName:(NSString *) name { NSString * str = [NSString stringWithFormat:@"age : 15, name : %@", name]; NSLog(@"%@", str); return str;}- (NSInteger) getAge { return 1970;}@end
2、测试:
代码中有详细的注释:
//// ViewController.m// 001-nsinvocation////#import "ViewController.h"#import "DZPerson.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor whiteColor]; DZPerson * p1 = [[DZPerson alloc] init]; //1、一个参数 NSMethodSignature * methodSignature1 = [[p1 class] instanceMethodSignatureForSelector:@selector(showName:)]; NSInvocation * invocation1 = [NSInvocation invocationWithMethodSignature:methodSignature1]; [invocation1 setTarget:p1]; [invocation1 setSelector:@selector(showName:)]; NSString * name = @"ldz"; //如果此消息有参数需要传入,那么就需要按照如下方法进行参数设置,需要注意的是,atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target 和selector占用 [invocation1 setArgument:&name atIndex:2]; //防止参数被释放掉 [invocation1 retainArguments]; //调用 [invocation1 invoke]; //2、两个参数 NSMethodSignature * methodSignature2 = [[p1 class] instanceMethodSignatureForSelector:@selector(showName:andAge:)]; NSInvocation * invocation2 = [NSInvocation invocationWithMethodSignature:methodSignature2]; [invocation2 setTarget:p1]; [invocation2 setSelector:@selector(showName:andAge:)]; NSUInteger age = 18; [invocation2 setArgument:&name atIndex:2]; [invocation2 setArgument:&age atIndex:3]; [invocation2 retainArguments]; [invocation2 invoke]; //3、有返回值的情况 NSMethodSignature * methodSignature3 = [[p1 class] instanceMethodSignatureForSelector:@selector(getAgeAndNameWithName:)]; NSInvocation * invocation3 = [NSInvocation invocationWithMethodSignature:methodSignature3]; [invocation3 setTarget:p1]; [invocation3 setSelector:@selector(getAgeAndNameWithName:)]; [invocation3 setArgument:&name atIndex:2]; [invocation3 retainArguments]; [invocation3 invoke]; //获取返回值类型 const char * returnValueType = methodSignature3.methodReturnType; NSLog(@"returnValueType : %s", returnValueType); //声明一个返回值变量 id returnValue; //如果没有返回值,也就是消息声明为void,那么returnValue = nil if (!strcmp(returnValueType, @encode(void))) { NSLog(@"没有返回值,即返回值类型为void"); returnValue = nil; }else if (!strcmp(returnValueType, @encode(id))){ //如果返回值为对象,那么为变量赋值 NSLog(@"返回值类型为对象"); [invocation3 getReturnValue:&returnValue]; }else { //如果返回值为普通类型,如NSInteger, NSUInteger ,BOOL等 NSLog(@"返回类型为普通类型"); //首先获取返回值长度 NSUInteger returnValueLenth = methodSignature3.methodReturnLength; //根据长度申请内存 void * retValue = (void *)malloc(returnValueLenth); //为retValue赋值 [invocation3 getReturnValue:retValue]; if (!strcmp(returnValueType, @encode(BOOL))) { returnValue = [NSNumber numberWithBool:*((BOOL *)retValue)]; }else if (!strcmp(returnValueType, @encode(NSInteger))){ returnValue = [NSNumber numberWithInteger:*((NSInteger *) retValue)]; } //。。。 余下省略 } NSLog(@"返回值是:%@", returnValue); //4、返回类型为普通类型的情况 NSMethodSignature * methodSignature4 = [[p1 class] instanceMethodSignatureForSelector:@selector(getAge)]; NSInvocation * invocation4 = [NSInvocation invocationWithMethodSignature:methodSignature3]; [invocation4 setTarget:p1]; [invocation4 setSelector:@selector(getAge)]; [invocation4 invoke]; //获取返回值类型 const char * returnValueType4 = methodSignature4.methodReturnType; NSLog(@"returnValueType : %c", *returnValueType4); //声明一个返回值变量 id returnValue4; //如果没有返回值,也就是消息声明为void,那么returnValue = nil if (!strcmp(returnValueType4, @encode(void))) { NSLog(@"没有返回值,即返回值类型为void"); returnValue4 = nil; }else if (!strcmp(returnValueType4, @encode(id))){ //如果返回值为对象,那么为变量赋值 NSLog(@"返回值类型为对象"); [invocation4 getReturnValue:&returnValue4]; }else { //如果返回值为普通类型,如NSInteger, NSUInteger ,BOOL等 NSLog(@"返回类型为普通类型"); //首先获取返回值长度 NSUInteger returnValueLenth4 = methodSignature4.methodReturnLength; //根据长度申请内存 void * retValue4 = (void *)malloc(returnValueLenth4); //为retValue赋值 [invocation4 getReturnValue:retValue4]; if (!strcmp(returnValueType4, @encode(BOOL))) { returnValue4 = [NSNumber numberWithBool:*((BOOL *)retValue4)]; }else if (!strcmp(returnValueType4, @encode(NSInteger))){ returnValue4 = [NSNumber numberWithInteger:*((NSInteger *) retValue4)]; } //。。。 余下省略 } NSLog(@"返回值是:%@", returnValue4); }- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
输出:
2016-02-16 14:23:00.093 001-nsinvocation[2766:96619] name : ldz2016-02-16 14:23:00.094 001-nsinvocation[2766:96619] name : ldz, age : 182016-02-16 14:23:00.094 001-nsinvocation[2766:96619] age : 15, name : ldz2016-02-16 14:23:00.094 001-nsinvocation[2766:96619] returnValueType : @2016-02-16 14:23:00.094 001-nsinvocation[2766:96619] 返回值类型为对象2016-02-16 14:23:00.094 001-nsinvocation[2766:96619] 返回值是:age : 15, name : ldz2016-02-16 14:23:00.094 001-nsinvocation[2766:96619] returnValueType : q2016-02-16 14:23:00.095 001-nsinvocation[2766:96619] 返回类型为普通类型2016-02-16 14:23:00.095 001-nsinvocation[2766:96619] 返回值是:1970
3、其中Objective-C类型编码为:
编码含义cchariintsshortllong在64位程序中,l为32位qlong longC(大写)unsigned charI(大写)unsigned intS(大写)unsigned shortLunsigned longQunsigned long longffloatddoubleBC++标准的bool或者C99标准的_Boolvvoid*字符串(char *)@对象(无论是静态指定的还是通过id引用的)#类(class):方法选标(SEL)[array type]数组{name=type...}结构体(name=type...)联合体bnumnum个bit的位域^typetype类型的指针?未知类型(其他的情况,一般用来指函数指针)
0 0
- NSInvocation简单用法
- NSInvocation用法
- IOS NSInvocation用法
- NSInvocation的一种用法
- NSInvocation的用法
- iOS NSInvocation用法
- IOS NSInvocation用法简介
- IOS NSInvocation用法
- NSInvocation的基本用法
- NSInvocation的基本用法
- NSInvocation的基本用法
- NSInvocation用法简介
- iOS NSInvocation用法简介
- NSInvocation的用法
- NSInvocation的基本用法
- NSInvocation的基本用法
- NSInvocation简单使用
- NSInvocation简单使用
- Android studio插件GsonFormat,返回json快速创建实体对象
- JAVA Spring面试题
- linux命令笔记
- 矩阵和向量
- 使用Selenium通过浏览器对网站进行自动化测试
- NSInvocation简单用法
- epoll示例程序——客户端
- 从今天起坚持写博客
- java环境变量配置
- Android Activity 生命周期
- Spark应用程序的测试与发布
- Cookie
- cacti 部署
- Lingo函数