ios - NSInvocation 和引用参数

标签 ios objective-c

我正在使用 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/

相关文章:

ios - 如何链接两个相互连接的 Collection View ?

iphone - UItableView 中的 CustomCell 崩溃

ios - CoreData在启动时检测数据库不一致

ios - 更改任何 swift 代码后 Umbrella 头文件未更新

objective-c - 用于检查在 iOS 应用程序中输入的用户名和密码的 If 语句

iphone - 将 facebook api 用于 ios sdk 的问题

ios - 有没有办法允许某些类访问某些其他类的私有(private)属性?

ios - 在 xcode8 中找不到 ModuleName-Swift.h 文件

iOS 7 - 单击时正确选择/取消选择行

ios - 如何将刷新控件应用于 UITableView