我正在使用 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];
}
最佳答案
找到了!
by reference 参数需要声明为 __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];
}
关于ios - NSInvocation 和引用参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26019686/