6

オブジェクトに「フック」を設定して、どのメッセージがオブジェクトに送信されているかを確認するにはどうすればよいですか?(つまり、メッセージがオブジェクトに送信されるたびにNSLog()を実行します)。

以前にこれが行われたのを見たことを思い出すと思いますが、その方法を忘れています。コードの一部が機能しない理由を突き止めるのに役立つかもしれないと思っています。

4

4 に答える 4

18

Objective-C転送を使用することもできます。基本的に、メソッドをログに記録してから呼び出しを元のオブジェクトに転送するプロキシオブジェクトを作成できます。詳細については、私のブログ投稿を参照してください。

@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
于 2009-08-25T13:30:20.520 に答える
8

これを行う最良の方法は、dtraceまたはinstrumentsスクリプトを使用することです。dtraceを使用すると、次のことができます。

次のスクリプトをobjc-calls.dとして記述します

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

次に、スクリプトを使用してアプリを実行します。

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

同様のdtraceプローブを使用してカスタム機器を構築することもできます。

于 2009-08-25T12:59:00.193 に答える
1

昨年のLouisGerbargのコメントに続いて、クラス名で簡単にフィルタリングできることも便利です。

次の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.dsudo objc-calls.d -c /Your/Binary NSObjectNSObject(およびそのカテゴリ)に関連する呼び出しのみを表示します。

于 2010-09-30T22:39:04.977 に答える
0

オブジェクトを使用して、メソッドNSProxyをオーバーライドできます。forwardInvocation:

于 2009-08-25T12:26:10.683 に答える