2014-09-24 95 views
1

我正在使用NSInvocation來調用一個我在編譯時不知道的方法。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]; 
} 
+0

說實話,我想嘗試不同的方法。很少有機會可以正確處理NSError * __autoreleasing *參數。 – gnasher729 2014-09-24 15:33:51

+0

@ gnasher729,你會推薦什麼? – 2014-09-24 16:12:12

+0

我可能會嘗試使用一個塊或一個switch語句來處理多個函數等 – gnasher729 2014-09-25 13:37:23

回答

0

發現它沒有工作!

所需的參照參數聲明爲__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]; 
}