有时候,写程序的时候会用到自己以前写的东西,但某些接口是不对外开放的,只有我自己知道。这个时候,可以使用如下方法来调用那些实际存在但被藏起来的方法。
objc_msgSend
根据objective-c的运行时特性,向某个对象或对象的实例发送消息,最终调用的其实是objc_msgSend。
objc_msgSend(receiver, selector, arg1, arg2, …);
第一个参数为方法的接收对象,第二个参数为SEL,后面是方法需要的参数。
performSelector
最多带两个参数,且参数为object,不能是int之类的基础类型
新建一个工程,在ViewController.m里面定义一些方法
- (void)function0
{
NSLog(@"no par");
}
- (void)function1:(NSString *)first
{
NSLog(@"one par,=%@",first);
}
- (void)function2:(NSString *)first second:(NSString *)second
{
NSLog(@"two par,first =%@,second=%@",first,second);
}
- (void)function3:(NSString *)first second:(NSString *)second third:(int)third
{
NSLog(@"third par,first =%@,second=%@,third=%d",first,second,third);
}
对于function0,function1, function2可以使用performSelector调用
[self performSelector:@selector(function0) withObject:nil];
[self performSelector:@selector(function1:) withObject:@"aaaa"];
[self performSelector:@selector(function2:second:) withObject:@"xxxx" withObject:@"yyyy"];
打印出的东西如下:
但对于function3来说,超过2个参数,如果使用performSelector:withObject:withObject:withObject的方式,xcode会直接提示错误,编译就不能通过。
这个时候只能用到NSInvocation
NSInvocation
如果是实例方法,那么可以使用如下代码
SEL mySelector = @selector(function3:second:third:);
id target = self;
NSMethodSignature* signature1 = [self methodSignatureForSelector:mySelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature1];
[invocation setTarget:target];
[invocation setSelector:mySelector];
NSString * f = @"mmmm";
NSString * s = @"nnnn";
int i = 100;
[invocation setArgument:&f atIndex:2];
[invocation setArgument:&s atIndex:3];
[invocation setArgument:&i atIndex:4];
[invocation invoke];
如果是类方法,那么方法签名应该是类签名
NSMethodSignature* signature1 = [[self class] methodSignatureForSelector:mySelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature1];
要获取返回值
performSelector并没有获取返回值的功能。如果你需要某个方法的返回值,那么只能使用NSInvocation。
假如说使用上方介绍的NSInvocation,那么要获得返回值,应该这样做。
//假如说有个NSString类型的返回值
…………
…………
NSString * result;
[invocation getReturnValue:&result];
[invocation invoke];
参考
2.http://stackoverflow.com/questions/2716143/sel-performselector-and-arguments