2014-05-22 118 views
1

我使用運行時功能向類添加類方法,但是此方法不能被NSInvocation使用。我的代碼是這樣的:iOS:通過class_addMethod添加的類方法不能被NSInvocation使用

id metaClass = object_getClass((id)protocolClass); 
IMP prevImp = class_replaceMethod(metaClass, @selector(xxx), imp, NULL); 

const char *selectorName = sel_getName(@selector(xxx)); 
char newSelectorName[strlen(selectorName) + 10]; 
strcpy(newSelectorName, "ORIGIN"); 
strcat(newSelectorName, selectorName); 
SEL newSelector = sel_getUid(newSelectorName); 
if(!class_respondsToSelector(metaClass, newSelector)) { 
    class_addMethod(metaClass, newSelector, prevImp, NULL); 
} 

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: 
          [protocolClass methodSignatureForSelector:newSelector]]; 

調用創建語法崩潰爲:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSMethodSignature signatureWithObjCTypes:]: type signature is empty.' 
*** First throw call stack: 
(
    0 CoreFoundation      0x07c251e4 __exceptionPreprocess + 180 
    1 libobjc.A.dylib      0x079a48e5 objc_exception_throw + 44 
    2 CoreFoundation      0x07c13ce4 +[NSMethodSignature signatureWithObjCTypes:] + 1172 
    3 CoreFoundation      0x07cc22e9 +[NSObject(NSObject) methodSignatureForSelector:] + 73 
     ...... 
) 

任何解釋?我需要使用NSInvocation的原因是因爲我想要選擇器的返回值,還有其他方法嗎?

+0

如果您知道此選擇器的簽名(其返回類型以及所需的參數類型),則可以手動形成方法簽名。 – matt

+0

也可以使用調試器確保您獲得整個值。例如,可能'newSelector'爲零。 – matt

回答

2

您需要傳遞方法的簽名字符串作爲class_addMethod的第4個參數。你通過NULL