1

Objective-C の新機能。厳密に型指定された OO 言語でコードを記述するときは、コード内で設計をできるだけ明示的にするのが好きです。また、パラメーター値の範囲などをチェックして、プログラムの正確性を維持していることを確認するのも好きです (たとえば、メソッドの開始時に、オブジェクト参照が null でないことを確認し、可能な限り定数を使用してください..)。これらの簡単なチェックは、同僚と私が開発中に問題を発見するのに役立ちました。

現在、objective-c で作業しているため、プロトコルの実装にメッセージを送信する前に、セレクターがサポートされていることを確認したくなります。または、 内のオブジェクトの型の互換性を手動で確認しますNSArray

これらのタイプのチェックは、objective-c プログラムでは正常ですか? これらのチェックが必要になるのはいつですか。

前もって感謝します。

4

3 に答える 3

2

あなたがやろうとしていることは完全に受け入れられますが、必ずしもすべてのプログラマーのアプローチのパンとバターではありません. (私はいつもこれをしているわけではありませんが、そうすべきかもしれません。)

チェックする方法は次のようになります。

if([someObject respondsToSelector:@selector(someSelector)]){
  [someObject someSelector];
}

応答しないオブジェクトにメッセージを送信すると、ランタイム クラッシュが発生します。事前に確認すると、ロジックが完全にオフになっている可能性があります。(一般的な例は、1 つのオブジェクトを扱っていると思っていても、実際にはまったく別のものを扱っている場合です。これにより、開発中のクラッシュと実行時の期待値/動作との間のトレードオフが生じます。

慎重にコーディングすれば、詳細なチェックよりもはるかに先に進むことができます。

編集:

あなたの質問についてもう少し考えてみると、ランタイムはconformsToProtocol:メソッドも提供します。これにより、クラスまたはインスタンスがプロトコルに準拠しているかどうかを確認できます。これはまさにあなたが望むもののようです。

どんなに注意してもクラッシュしないためにこれが実際に不可欠なのは、下位互換性を維持しながら新しい iOS 機能のサポートを追加する場合です。(そのような場合、新しいフレームワークに対して弱いリンクを作成し、これらとまったく同じチェックを使用して互換性を確保します。  

他の人が指摘しているように、プロトコルに関しては、何らかの形式のコンパイル時チェックが行われます。メソッドが として示されていない場合@optional、Xcode は不完全な実装について警告します。

于 2012-12-13T03:25:04.503 に答える
1

プロトコル定義がメソッドを@requiredチェックとして宣言している場合、チェックは冗長であり、@optionalチェックしている場合は必須です。防弾コードが必要な場合は、配列内のオブジェクトの型を確認することをお勧めします (ただし、パフォーマンスが低下する可能性があります)。しかし、私は自分で行ったことはありません。

于 2012-12-13T03:24:28.373 に答える
1

プロトコルについては、メソッドを として宣言する場合@optional、実装はオプションであるため、オブジェクトが実際にセレクターに応答するかどうかを確認する必要があります (通常、呼び出しごとにチェックするのではなく、チェックの結果をキャッシュします)。オプションでない場合は、テストしないでください。コンパイラーは実装されていないセレクターに対して警告を発するため、とにかく失敗したいだけであれば、実行時チェックは実際には必要ありません (実行時は例外をスローし、デバッガーは中断するため、何が欠けているかがわかります)。 .

配列内のオブジェクトのチェックについては可能ですが、通常、すべてのオブジェクトを受け入れたくない場合は、配列自体をエクスポートするのではなく、 のようなメソッドをエクスポートしますaddMyObject:(AllowedObject *)object。明らかに、配列をパラメーターとして受け入れ、その中のすべてのオブジェクトが準拠していることを確認したい場合は、オブジェクトをチェックする必要があります (配列を反復処理するとき、またはそのようなものを呼び出してindexesOfObjectsPassingTest:返されたオブジェクトがあるかどうかを確認するかのいずれか)。必要に応じてNSIndexSet、配列と同じ数 (またはNSIndexSet、元の配列から を取得して、それによって記述された部分配列を取得し、それを操作することもできます)。

ただし、Objective-Cs ランタイムのため、必ずしもすべてのメソッド呼び出しをチェックする必要はありません。サポートされていない場合、デバッガーが壊れ、何が問題なのかを判断できます。ただし、マクロを使用してパラメータの有効性を確認することをお勧めしNSAssertます (ユニット テストをまだ行っていない場合は、ユニット テストを記述します。これにより、一時的に頭痛の種を大幅に減らすこともできます!)。

于 2012-12-13T03:25:39.137 に答える