2013-01-16 70 views
1

我想使用NSClassFromString和NSSelectorFromString爲類方法和選擇器構建調用。 我試圖建立以下列方式調用:如何構建類方法的NSInvocation?

NSMethodSignature *signature; 
NSInvocation *inv; 

Class targetClass = NSClassFromString(@"NSString"); 
SEL selector = NSSelectorFromString(@"stringWithString:"); 
id arg = @"argument"; 

Method method = class_getInstanceMethod(targetClass, selector); 

//爲什麼是方法零當我運行的代碼?

struct objc_method_description* desc = method_getDescription(method); 

if (desc == NULL || desc->name == NULL){ 
    return nil; 
} 

signature = [NSMethodSignature signatureWithObjCTypes:desc->types]; 
inv = [NSInvocation invocationWithMethodSignature:signature]; 
[inv setSelector:selector]; 
[inv setArgument:&arg atIndex:2]; 
[inv invoke]; 

__autoreleasing id returnObj;  
[inv getReturnValue:&returnObj]; // get created object 

由於'方法'總是'零',所以此方法不起作用。爲什麼?
通過調用上述代碼來執行類方法的正確方法是什麼?

回答

6

您的代碼太複雜了。您可以獲得一個NSMethodSignature*對象,而不會混淆運行時。

signature = [NSString methodSignatureForSelector:@selector(stringWithString:)]; 
+0

謝謝!這是較短的代碼。但是返回結果是零。我試過: id res = [NSString stringWithString:@「7」]; // SEL sel; NSMethodSignature * sig; NSInvocation * inv; Class targetClass; targetClass = NSClassFromString(@「NSString」); selector = NSSelectorFromString(@「stringWithString:」); sig = [targetClass methodSignatureForSelector:sel]; inv = [NSInvocation invocationWithMethodSignature:sig]; [inv setSelector:sel]; id arg = @「7」; [inv setArgument:&arg atIndex:2]; [inv invoke]; id retObj; [inv getReturnValue:&retObj] // retObj is nil(I expected @「7」) – sg7

+1

@ sg7:您正在調用'[inv invoke]',但是您從不設置目標。您需要設置目標,或者只需使用'[inv invWithTarget:targetClass]'。 –

+0

非常感謝! [inv invokeWithTarget:targetClass];糾正我的代碼!非常感謝您的幫助! – sg7

2

stringWithString:是一種類方法,您的代碼使用的是class_getInstanceMethod()

嘗試更改class_getInstanceMethod()class_getClassMethod()

+0

謝謝!這直接糾正了原始代碼並解決了無法解決**的問題!然而,returnObj是零,而不是預期的@「參數」 – sg7

+0

正如凱文巴拉德指出,我錯過了設置目標!用'[inv invokeWithTarget:targetClass];'並且使用'class_getClassMethod()'代替'[inv invoke];'後,對於原始代碼,一切正常。謝謝! – sg7

相關問題