2011-01-06 2 views
19

forwardInvocation을 작동시키는 데 문제가 있습니다. 어떤 이유로 Objective-C 런타임은 forwardInvocation : 메서드를 완전히 무시하고 인식 할 수없는 선택기 예외를 발생시킵니다.forwardInvocation이 호출되지 않습니까?

@interface InvocationTest : NSObject 
{ 
} 

+ (void) runTest; 

@end 


@interface FullClass: NSObject 
{ 
    int value; 
} 
@property(readwrite,assign) int value; 

@end 

@implementation FullClass 

@synthesize value; 

@end 


@interface SparseClass: NSObject 
{ 
} 

@end 

@implementation SparseClass 

- (void)forwardInvocation:(NSInvocation *)forwardedInvocation 
{ 
    NSLog(@"ForawrdInvocation called"); 

    FullClass* proxy = [[[FullClass alloc] init] autorelease]; 
    proxy.value = 42; 
    [forwardedInvocation invokeWithTarget:proxy]; 
} 

@end 


@implementation InvocationTest 

+ (void) runTest 
{ 
    SparseClass* sparse = [[[SparseClass alloc] init] autorelease]; 
    NSLog(@"Value = %d", [sparse value]); 
} 

@end 

을 나는 다음과 같은 자원의 정보를 일하고 있어요 : 내가 말할 수있는

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105 http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

는 지금까지, 런타임해야 다음과 같이

내 테스트 코드는 forwardInvocation을 호출하는 중 : [희소 가치]를 호출 할 때 SparseClass의 인스턴스에서 호출되지만 완전히 무시됩니다.

,451,515,

는 - [SparseClass 값] - :

'인식 선택기 인스턴스 0x4b1c4a0 전송 [SparseClass 값]'인식 선택기 인해 캐치되지 않는 예외 'NSInvalidArgumentException'이유 응용 프로그램 종료 *** 인스턴스 0x4b1c4a0 보내

답변

36

작동하려면 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector을 다시 정의해야합니다.

나는

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 
    return [FullClass instanceMethodSignatureForSelector:aSelector]; 
} 

가 확인을해야 같아요. NSObject 문서에서

+1

굉장! 매력처럼 일했습니다. – Karl

24

:

중요 : 개체 자체가, 당신이 forwardInvocation:에 추가 methodSignatureForSelector:를 오버라이드 (override) 할 필요가 인식하지 못하는 방법에 응답 할 수 있습니다. 메시지 전달 메커니즘은 methodSignatureForSelector:에서 가져온 정보를 사용하여 전달할 NSInvocation 개체를 만듭니다. 오버라이드 (override)하는 메소드는, 지정된 셀렉터에 대해, 메소드를 사전에 형식화하거나 다른 객체에 요구하는 것에 의해, 적절한 메소드 서명을 제공 할 필요가 있습니다. 객체는 수신 원격 메시지를 전달하는 경우, 그것은 궁극적으로 반응하는 방법에 대한 정확한 설명을 반환 할 수 methodSignatureForSelector:의 버전이 있어야합니다 ...

다음 runtime 문서에서

그리고, 전달 된 메시지; 객체가 대리로 메시지를 전달할 수있는 경우는 다음과 같이 예를 들어, 당신은 methodSignatureForSelector: 구현하는 것이 :

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector 
{ 
    NSMethodSignature* signature = [super methodSignatureForSelector:selector]; 
    if (!signature) { 
     signature = [surrogate methodSignatureForSelector:selector]; 
    } 
    return signature; 
} 

참고 : 참조 Jilouc의 answermethodSignatureForSelector:의 적절한 이행을위한.

+13

Apple의 런타임 프로그래밍 가이드 문서가이 문제에 관해 실패한다고 생각합니다. "Forwarding"섹션에서 그들은'methodSignatureForSelector :'와'forwardInvocation :'을 필요로하지 않는다는 것을 언급하지 않습니다. 그 맛있는 음식을 찾으려면 3 가지 섹션을 아래로 스크롤하여 섹션 방법을 구현해야하는지 확인하십시오. – DBD