2
- (NSDictionary*)convertMessage:(Message*)event
{
    // if this gets called then a derived class either didn't override this function or it called [super convertEvent:event]
    [self doesNotRecognizeSelector:_cmd];
    return nil;
}

結果の値はnilになると予想しています。

-(void)calling{

 NSDictionary *dictionary  = [self convertMessage:evt];

}

しかし、そのことわざ認識されないセレクターがエラーブロックのためにインスタンスに送信されました!走っているとき!

4

2 に答える 2

2

の実装は[self doesNotRecognizeSelector:_cmd]、例外をスローすることです。したがって、期待される結果は例外が発生します。nilが返されることを期待している場合は、メソッドでnilを返すだけで、呼び出さないでください。doesNotRecognizeSelector:

アップルのドキュメントを参照してください

ランタイムシステムは、オブジェクトが応答または転送できないaSelectorメッセージを受信するたびに、このメソッドを呼び出します。次に、このメソッドはNSInvalidArgumentExceptionを発生させ、エラーメッセージを生成します。

doesNotRecognizeSelector:メッセージは通常、ランタイムシステムによってのみ送信されます。ただし、これらをプログラムコードで使用して、メソッドが継承されないようにすることができます。たとえば、NSObjectサブクラスは、次のように、doesNotRecognizeSelector:メッセージを含めるように再実装することにより、copyまたはinitメソッドを放棄する場合があります。

- (id)copy {
    [self doesNotRecognizeSelector:_cmd];
}

_cmd変数は、現在のセレクターであるすべてのメソッドに渡される非表示の引数です。

この例では、copyメソッドのセレクターを識別します。このコードは、サブクラスのインスタンスがコピーメッセージに応答したり、スーパークラスがコピーメッセージを転送したりするのを防ぎます。ただし、respondsToSelector:は、受信者がコピーメソッドにアクセスできることを報告します。

このメソッドをオーバーライドする場合は、実装の最後にsuperを呼び出すか、NSInvalidArgumentException例外を発生させる必要があります。 つまり、このメソッドは正常に戻らないようにする必要があります。常に例外がスローされる必要があります。

于 2013-02-26T09:18:27.393 に答える
2

@ xlc0212の答えを拡張するには:

メソッドの元の実装...

[self doesNotRecognizeSelector:_cmd];
return nil;

return...ステートメントに到達することは期待されていませんでした。@ xlc0212で説明されてdoesNotRecognizeSelectorいるように、例外がスローされ、プロセスが異常終了します。

実装の作成者はreturn、コンパイラの警告を黙らせるためにステートメントをそこに置くだけです。これを行うためのより現代的で混乱の少ない方法は、コードのこのポイントに到達できなかったことをclangに伝えることです。

- (NSDictionary*)convertMessage:(Message*)event
{
    [self doesNotRecognizeSelector:_cmd];
    __builtin_unreachable();
}
于 2013-02-26T09:24:46.877 に答える