5

Objective-C の「メッセージ転送」について勉強しています。実行時に認識されないセレクターを「飲み込む」ことができるかどうかを検証するテスト プログラムを作成します。だから私はこれをしました:

- (void) forwardInvocation: (NSInvocation *) anInvocation {
    if ([anInvocation selector] == @selector(testMessage)){
       NSLog(@"Unknow message");
    }
    return;
}

ただし、実行時に「認識されないセレクター」エラーがスローされます。解決策を検索した後、メソッド「methodSignatureForSelector:」をオーバーライドする必要があることがわかったので、「Proxy」という別のプロキシ クラスと次のメソッドを記述します。

(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    if ([Proxy instancesRespondToSelector: selector]) {
        return [Proxy instanceMethodSignatureForSelector: selector];
    }   
    return [super methodSignatureForSelector:selector];
}

しかし、実際には、このメソッドを実現するために、そのような別のプロキシ クラスを実装したくありません。私がやりたいのは、この未知のセレクターを無視することだけです。しかし、これを入力しただけでは機能しません。

(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {   
    return [super methodSignatureForSelector:selector];
}

それで、このエラーを単純に「飲み込む」方法があるのだろうか?(例外ハンドラを使用していない、「転送」のような方法が欲しい)。ありがとう!

4

1 に答える 1

3

おそらく署名オブジェクトを生成する必要がありますが、これは少しトリッキーです:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    NSMethodSignature *sig = [super methodSignatureForSelector:selector];
    if (!sig) {
        if (selector == @selector(testMessage)) {
            // Create a signature for our fake message.
            sig = [NSMethodSignature signatureWithObjCTypes:"@:"];
        }
    }
    return sig;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
   // Do whatever you want with the invocation.
}

最大の問題は への引数のようsignatureWithObjCTypes:です。Apple の型エンコーディングに関するドキュメントを参照してください。すべてのメソッドには、少なくとも 2 つの引数id self(type @) とSEL _cmd(type :) があります。

別の方法は、ダミーのメソッドを用意し- (void)dummy { }、それを使用sig = [super methodSignatureForSelector:@selector(dummy)];して偽のメソッドの署名を取得することです。

于 2011-11-07T11:19:56.873 に答える