我使用NSInvocation来调用一个方法,在编译时我不知道这个方法。
它工作得很好,我没有找到如何传递NSError**类型的参数。
举个例子,假设我想从-(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error调用NSFileManager方法。
代码应该如下所示:
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];
}发布于 2014-09-25 12:46:10
找到了!
需要将by引用参数声明为__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];
}https://stackoverflow.com/questions/26019686
复制相似问题