I'm using NSInvocation
to call a method, which I don't know at compile time.
It works fine, by I didn't find how to pass an argument of type NSError**
.
Just as an example, suppose I want to call the method -(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
from NSFileManager
.
The code would look something like this:
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**
This is a simplified example. I avoided adding the error-checking code to make it easier to read.
Also, I don't know the type of the arguments at compile time, I just get the parameters as id
.
This is what I tried, but didn't work
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];
}
Found it!
The by reference parameter needed to be declared as __autoreleasing
This is the code that is working now:
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];
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.