2014-09-24 70 views
1

我正在使用NSInvocation来调用一个我在编译时不知道的方法。NSInvocation和参考参数

它工作正常,我没有找到如何通过NSError**类型的参数。

举一个例子,假设我想从NSFileManager调用方法-(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error

的代码会是这个样子:

NSFileManager *manager = [NSFileManager defaultManager]; 
SEL selector = @selector(removeItemAtPath:error:); 
NSMethodSignature *signature = [manager methodSignatureForSelector:selector]; 
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
[invocation setTarget:manager]; 
[invocation retainArguments]; 
[invocation setSelector:selector]; 

NSString *path = ...; 
[invocation setArgument:&path atIndex:2]; 
NSError *error = ...; 
[invocation setArgument:&error atIndex:3]; // Passing NSError*, not NSError** 

这是一个简单的例子。我避免添加错误检查代码以使其更易于阅读。

此外,我不知道编译时参数的类型,我只是得到参数为id

这是我尝试过,但

id argument = ... 
NSUInteger index = ... 
const char *argType = [signature getArgumentTypeAtIndex:index]; 
if (strcmp(argType, "^@") == 0) { 
    // object pointer 
    id __strong *argumentPointer = &argument; 
    [invocation setArgument:&argumentPointer atIndex:index]; 
} 
else { 
    [invocation setArgument:&argument atIndex:index]; 
} 
+0

说实话,我想尝试不同的方法。很少有机会可以正确处理NSError * __autoreleasing *参数。 – gnasher729 2014-09-24 15:33:51

+0

@ gnasher729,你会推荐什么? – 2014-09-24 16:12:12

+0

我可能会尝试使用一个块或一个switch语句来处理多个函数等 – gnasher729 2014-09-25 13:37:23

回答

0

发现它没有工作!

所需的参照参数声明为__autoreleasing

这是现在的工作代码:

id __autoreleasing argument = ... 
NSUInteger index = ... 
const char *argType = [signature getArgumentTypeAtIndex:index]; 
if (strcmp(argType, "^@") == 0) { 
    // object pointer 
    NSObject * __autoreleasing *argumentPointer = &argument; 
    [invocation setArgument:&argumentPointer atIndex:index]; 
} 
else { 
    [invocation setArgument:&argument atIndex:index]; 
}