转载自jiangamh. 原文地址
-(void)method1Test{
NSLog(@"method1Test");
}
-(NSInteger)mehtod2Test{
NSLog(@"method2Test");
return 1;
}
-(ViewController*)method3Test:(NSString*)str{
NSLog(@"参数:%@",str);
return self;
}
- (void)viewDidLoad{
[super viewDidLoad];
[self nsInvocationTest];
}
-(void)nsInvocationTest
{
//情况一 无参数,无返回值
//通过选择器获取方法签名
SEL selector = @selector(method1Test);
NSMethodSignature *methodSign = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation *methodInvocation = [NSInvocation invocationWithMethodSignature:methodSign];//通过方法签名获得调用对象
[methodInvocation setSelector:selector]; //设置selector
[methodInvocation setTarget:self]; //设置target
[methodInvocation invoke]; //执行
//情况二 有返回值,无参数
selector = @selector(mehtod2Test);
methodSign = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation *mehtod2Invocation = [NSInvocation invocationWithMethodSignature:methodSign];
[mehtod2Invocation setSelector:selector]; //设置selector
[mehtod2Invocation invokeWithTarget:self]; //设置target 并执行
NSInteger returnValue = 0;
[mehtod2Invocation getReturnValue:&returnValue]; //获取返回值
NSLog(@"method2Test返回值:%ld",returnValue);
//情况三 有返回值,有参数
selector = @selector(method3Test:);
NSMethodSignature *method3Sign = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation *method3Invocation = [NSInvocation invocationWithMethodSignature:method3Sign];
[method3Invocation setSelector:selector]; //设置selector
[method3Invocation setTarget: self]; //设置target
NSString *arg1 = @"testArg1";
[method3Invocation setArgument:&arg1 atIndex:2]; //设置参数
[method3Invocation invoke]; //执行
//获取返回值
/**
崩溃: 当返回值为对象是,arc情况下容易出现崩溃问题,如下两种解决方案。
原因: arc下vc如果用strong的,默认NSInvocation实现认为,已经对返回对象retain一次,实际上并没有,当返回对象出了作用域时候,已经被收回。导致崩溃。
*/
//解决方案1
void *vc = nil;
[method3Invocation getReturnValue:&vc];
NSLog(@"vc:%@",(__bridge ViewController*)vc);
//解决方案2
UIViewController * __unsafe_unretained vc = nil;
[method3Invocation getReturnValue:&vc];
NSLog(@"vc:%@",vc);
}