13

- mobileorchard.com - Chattyからダウンロードしたコードに関連する疑問を解消したかっただけです。研究開発中に、ChatRoomViewController.mファイルで関数呼び出しを見ました。

 [chatRoom broadcastChatMessage:input.text fromUser:[AppConfig getInstance].name];

上記の呼び出しの実装のために、Room.mファイルで見たとき。そうだった

- (void)broadcastChatMessage:(NSString*)message fromUser:(NSString*)name
{
    // Crude way to emulate an "abstract" class
    [self doesNotRecognizeSelector:_cmd];
}

「doesNotRecognizeSelector:」をグーグルで検索しました。Appleによると、エラー処理について、「オブジェクトが応答または転送できないaSelectorメッセージを受信するたびに、ランタイムシステムがこのメソッドを呼び出します」と述べています。私の質問は、開発者がBroadcastChatMessage:fromUser:関数を呼び出すのはなぜですか?

Stackovrflowによると、この質問によると、抽象クラスを作成するために使用され、「不完全な実装」警告を回避するために使用されます。

そのChatty Codeでそのメソッドが使用されている理由がまだわかりません。そのメソッドが使用されている理由を理解するのを手伝ってください。

4

2 に答える 2

12

これは、実行時の呼び出しでメソッドが認識されない場合に、例外へのパスをトリガーするすべてのNSObject派生オブジェクトに存在するメソッドです。たとえば、NSString呼び出された にメッセージを送信しようとすると-foo、 では有効なメソッドではないため、そこに送信されNSStringます。

この場合、Chatty クラスRoomは、直接使用されることのない基本クラスです。LocalRoomおよびRemoteRoomそれから派生し、これらのクラスの両方が のオーバーライド実装を提供します-broadcastChatMessage:fromUser。誰もその基本クラスのバージョンを呼び出したことはありませんが、「完全性」のために、プログラマーは、サブクラスがメソッドを実装することによってこれをオーバーライドする必要があることを保証しましたが、その後、向きを変えてこれを呼び出して例外をトリガーします。

問題は、これは具体的に慣用的な Objective-C ではないということです。「抽象」クラスは、C++ およびその他の言語の概念です。サブクラス化する「パターン」としてのみ存在するのは基本クラスです。(ObjC では、@protocol(ほとんどの場合) 存在しないため、意味のある状態がない場合にフォーマルを作成することによって、これが行われることがよくあります)。

への呼び出し-doesNotRecognizeSelector:は任意であることに注意してください。ここでコンパイラの警告を回避する必要はありません (メソッドが実際に実装されているため)。また、元の作成者は簡単に直接例外をスローするか、代わりに何もしない可能性があります。

于 2013-04-09T05:39:50.267 に答える
4

あなたはすでにあなた自身の質問に答えているようです。Objective-C には抽象クラスを作成するメソッドがないため、オーバーライドする必要があるメソッドに例外をスローさせるのに最も近い方法です。サブクラスでこのメソッドをオーバーライドすると、doesNotRecognizeSelector:呼び出されなくなります。基本的には、開発者にこのメソッドをサブクラスに実装することを約束させる方法です。

また、あなたが言及したように、これを入れないと、ヘッダーで定義されたメソッドの実装が存在しないため、コンパイラーは警告を発行します。これは、実装しない場合と同じ動作を実行しますが、コンパイラは、意図的に実行していることを認識します。

于 2013-04-09T05:39:54.017 に答える