这是我在简书上写的第一篇文章,想想还是挺激动的~~~
首先来一段苹果官方对于NSInvocation类的解释的翻译,我觉得看官方文档真的可以学到挺多东西的,是第一手资料。下面正式开始:
NSInvocation是一个静态消息类,把一个方法转化成一个对象。NSInvocation对象用来在对象与对象之间或者应用与应用之间存储和传递消息(这里的传递消息我姑且认为是对象对方法的调用以及方法所使用的参数以及返回值)。
一个NSInvocation对象包含一个oc消息所具有的所有元素:目标,选择器,参数,返回值。每一个元素都可以被直接设置,返回值会在invocation对象被执行的时候直接赋值。
一个NSInvocation对象可以被反复的分配给不同的target,参数也可以在invocation执行之前修改,选择器也可以在不改变方法签名的情况下修改成不同的值,这种灵活性使得invocation极为有用特别是在参数很多的情况下。所以我们在给一个invocation设置到一个新的target之前,只需要修改他的一些参数就可以了,而不是重新创建一个新的invocation对象。
NSInvocation不支持调用其他的类方法来创建对象,不管这个方法是有一个或者多个参数(这里没懂什么意思)。只能使用invocationWithMethodSignature:方法来创建一个NSInvocation对象,而不能使用alloc init方法创建对象。
invocation默认不对内部的参数进项强引用,如果这些参数在你创建或者使用invocation对象的时候会消失,你应该手动的去强引用这些参数或者调用invocation的retainArguments方法让invocation来强引用这些参数。
翻译完毕。再来一段网上大多人数人多说过的东西,NSInvocation类是为了弥补performSelector:withObject:只能传递一个参数,并且不能接受返回值的缺点而改进出来的类。我觉得NSInvocation类的功能很强大,隐隐有着运行时的特性了,具体有什么用还在学习,以后改进。
代码如下:
创建一个NSInvocation对象
//NSInvocation是一个调用静态消息传递对象
- (void)createInvocation{
//将 类与类的某一个方法 封装成方法签名对象
NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(doSomething:name2:)];
//利用方法签名创建消息调用对象,不能用alloc init创建
self.invocation = [NSInvocation invocationWithMethodSignature:signature];
//设置消息调用的参数,固定的target是参数1,selector是参数2
NSString *name1 = @"仰望星空";
NSString *name2 = @"的小哥";
[self.invocation setArgument:&name1 atIndex:2];
[self.invocation setArgument:&name2 atIndex:3];
//设置消息调用对象的调用者
self.invocation.target = self;
//设置消息调用对象的选择器
self.invocation.selector = @selector(doSomething:name2:);
self.returnValue = nil;
}
普通使用NSInvocation
/*在调用之前修改参数*/
- (IBAction)sendMessageChangePara:(id)sender{
NSString *name2 = @"Alice";
[self.invocation setArgument:&name2 atIndex:3];
[self.invocation invoke];
[self.invocation getReturnValue:&_returnValue];
NSLog(@"returnValue:%@",_returnValue);
}
在调用之前修改方法
- (IBAction)sendMessageChangeSelecter:(id)sender{
[self.invocation setSelector:@selector(addString:)];
[self.invocation invoke];
// [self.invocation getReturnValue:&_returnValue];
// NSLog(@"returnValue:%@",_returnValue);
}
/*在调用之前修改 target*/
- (IBAction)sendMessageChangeTarget:(id)sender{
NSString *oneString = [[NSString alloc]init];
self.invocation.target = oneString;
[self.invocation invoke];
[self.invocation getReturnValue:&_returnValue];
NSLog(@"returnValue:%@",_returnValue);
}
invocation执行的方法
- (NSString *)doSomething:(NSString *)name name2:(NSString *)name2{
NSLog(@"name:%@",name);
NSLog(@"name2:%@",name2);
return [name stringByAppendingString:name2];
}```
invocation执行的方法2
- (NSString *)addString:(NSString *)string1{
NSLog(@"string1:%@",string1);
// NSLog(@"string2:%@",string2);
// return [string1 stringByAppendingString:string2];
return string1;
}```
以后有什么新的东西会再来补充。
网友评论