简体   繁体   中英

NSInvocation and by reference parameters

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM