2009-08-25 2 views
6

개체에 "후크"를 넣어서 어떤 메시지가 전송되는지 확인할 수 있습니까? (즉, 메시지가 객체에 전송 될 때마다 NSLog()를 수행합니다).개체의 모든 메서드/메시지 호출 캡처

이전에 이런 일이 있었는지를 생각해 보았지만 어떻게 잊을 까 생각합니다. 내 코드의 일부가 작동하지 않는 이유를 추적하는 데 도움이 될 것이라고 생각합니다.

답변

18

objective-c forwarding을 사용할 수도 있습니다. 기본적으로 메서드를 기록한 프록시 개체를 만들어 호출을 원본으로 전달할 수 있습니다. 자세한 내용은 내 blog post을 참조하십시오.

@interface LoggerProxy : NSObject 
{ 
    id original; 
} 

- (id)initWithOriginal:(id) value; 

@end 
@implementation LoggerProxy 

- (id) initWithOriginal:(id)value 
{ 
    if (self = [super init]) { 
     original = value; 
    } 
    return self; 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel 
{ 
    NSMethodSignature *sig = [super methodSignatureForSelector:sel]; 
    if(!sig) 
    { 
     sig = [original methodSignatureForSelector:sel]; 
    } 
    return sig; 
} 

- (void)forwardInvocation:(NSInvocation *)inv 
{ 
    NSLog(@"[%@ %@] %@ %@", original, inv,[inv methodSignature], 
     NSStringFromSelector([inv selector])); 
    [inv invokeWithTarget:original]; 
} 

@end 
+2

방금이 도구를 사용해 보았는데 어느 정도 작동합니다. 나는 그것을 MKPinAnnotationView로 시도하고 있는데, [MKPinAnnotationView superlayer]를 호출하려고 할 때 NSInvalidArgumentException과 충돌한다. 그래서이 방법이없는 객체로 보내려고 했습니까? –

+0

귀하의 블로그 게시물 링크가 오래되었습니다. – mahboudz

0

NSProxy 개체를 사용하고 forwardInvocation: 메서드를 재정의 할 수 있습니다.

8

가장 좋은 방법은 dtrace 또는 계측기 스크립트를 사용하는 것입니다. 당신이 할 수있는 DTrace를 사용하면 다음과 같은 :

setenv DYLD_SHARED_REGION avoid 
sudo dtrace -s objc-calls.d -c /Path/To/Your/App/Binary 

또한 사용자 지정을 구축 할 수 있습니다 :

하면 스크립트를 사용하여 응용 프로그램을 실행 objc-calls.d 그런

#pragma D option quiet 
objc$target:::entry 
{ 
    printf("%s %s\n", probemod, probefunc); 
} 

로 다음과 같은 스크립트를 작성 비슷한 dtrace 프로브를 사용하는 장비.

+0

나는 당신의 도움이 북마크되었지만, 다른 하나는 더 빠르고 쉽게 솔루션을 제공합니다. 감사. – Jacob

1

작년의 Louis Gerbarg의 의견에 이어 쉽게 클래스 이름별로 필터링 할 수있는 것도 유용합니다.

는 다음의 D 스크립트보십시오 : 그것은 저장

#!/usr/sbin/dtrace -s 
#pragma D option quiet 
objc$target:::entry 
/strstr(probemod,$$1) != NULL/ 
{ 
    printf("%s %s\n", probemod, probefunc); 
} 

, chmod a+x objc-calls.d을 다음 NSObject의 (및 카테고리)에 관련된 바로 호출을 볼 수 sudo objc-calls.d -c /Your/Binary NSObject을한다.