2014-05-22 6 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'는 nil입니다. – matt

답변

2

class_addMethod의 네 번째 인수로 메서드의 서명 문자열을 전달해야합니다. NULL을 전달 중입니다.