2011-11-07 4 views
5

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

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

しかし、実行時に "認識できないセレクタ"エラーがスローされます。ので、私は「プロキシ」と呼ばれる別のプロキシクラスと、次のメソッドを記述します。「methodSignatureForSelector」:私はメソッドをオーバーライドする必要があることを知っている解像度検索した後

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

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

このエラーを単純に「飲み込む」方法はありますか? (例外ハンドラを使用していないので、私は "フォワーディング"のような方法でやりたいと思う)。ありがとう!

+0

Cf. http://stackoverflow.com/a/11531609/ –

答えて

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's type encoding documentationを参照してください。すべてのメソッドには少なくとも2つの引数があります:id self(タイプ@)とSEL _cmd(タイプ:)です。

もう1つの方法は、ダミーメソッド、たとえば- (void)dummy { }を使用し、次にsig = [super methodSignatureForSelector:@selector(dummy)];を使用して、偽装されたメソッドの署名を取得することです。

+0

それは動作します!ありがとう!しかし、もう1つ:あなたの提案に従って、forwardInvocation:メソッドの[anInvocationセレクタ]を呼び出そうとすると、エラーが発生します: **キャッチされていない例外 'NSInvalidArgumentException'のためアプリを終了しています、理由: ' - [NSInvocation getArgument :atIndex:]:範囲外のインデックス(1)[-1、0] '**、 なぜですか? –

+3

私は[this](http://www.cocoabuilder.com/archive/cocoa/289799-nsproxy-nsinvocation-question.html)を見つけました:* [NSMethodSignature signatureWithObjTypes:]のドキュメントが間違っています。型配列の最初の要素は、idやClass型ではなく、型指定された戻り値です。実際にはselectorパラメータの引数型を持たないMSMethodSignatureインスタンスが残っています*これはおそらく、 foo'の場合、 'signatureWithObjCTypes:'の引数に '' @: ''型が必要です。 – DarkDust

+0

umm ...私は見る...ありがとう! –

関連する問題