34

私は Objective-C を学んでおり、C/C++ のバックグラウンドを持っています。

  • オブジェクト指向 C++ では、親クラスで宣言されている場合でも、定義 (実装) する前に常にメソッドを宣言する必要があります。

  • 手続き型の C、IIRC では、同じコンパイル単位 (つまり、同じファイル) 内の別のものからのみ呼び出される限り、関数を定義するだけで済みます。 「extern」を使用して他の場所で宣言しないでください)。

  • 現在、Objective-C では、ヘッダー ファイルでセレクターを宣言する必要があるのは、セレクターが外部で使用される場合のみであり、.m ファイルでセレクターを作成して、それらを内部で呼び出すことができるようです。 .m ファイル。また、デリゲート メソッドまたは継承されたメソッドが (再) 定義されることはないようです。

私は正しい軌道に乗っていますか?Objective-C でセレクターを定義する必要があるのはいつですか?

4

3 に答える 3

78

Objective-C メソッドの場合、公開するメソッドを@interfaceヘッダー ファイルのセクションに配置するのが一般的な方法です。これにより、他のコードは .h のみをインクルードし、コードと対話する方法を知ることができます。順序ベースの「遅延宣言」は、C の関数と同じように機能します。順序付けによって解決できない依存関係がない限り、メソッド プロトタイプを宣言する必要はありませんが@implementation、必要に応じてメソッド プロトタイプを内部に追加できます。

そうです、あなたは正しい軌道に乗っています。継承されたメソッドのメソッド プロトタイプを繰り返さないでください — コンパイラは親のヘッダー ファイルでそれを見つけます。デリゲート メソッドは、カテゴリ内のプロトタイプとして定義され (クラスに追加)、必要に応じて実装されますが、デリゲートはメソッド プロトタイプを提供する必要はありません。これは既に定義されているためです。(明確にするために必要な場合は、それでも可能です。)

Objective-C を学習しているだけなので、この回答の残りの部分は、要求したよりもはるかに詳細です。あなたは警告されました。;-)


変数を (たとえばMyClass*の代わりにid) 静的に型付けすると、クラスが実装していることを公示していないメソッドを呼び出そうとすると、実装しているかどうかにかかわらず、コンパイラは警告を発します。変数を動的に型指定すると、コンパイラは好きなものを呼び出すのを止めません。また、存在しないものを呼び出した場合にのみ実行時エラーが発生します。言語に関する限り、クラスが実装する任意のメソッドを実行時にエラーなく呼び出すことができます。メソッドを呼び出すことができるユーザーを制限する方法はありません。

個人的には、これは本当に良いことだと思います。私たちは、自分のコードをカプセル化して他のコードから保護することに慣れすぎているため、発信者を信頼できる同僚や顧客ではなく、よこしまな悪党として扱うことがあります。「あなたはあなたの仕事をし、私は私の仕事をする」という考え方でコーディングするのはとても楽しいと思います。誰もが境界を尊重し、自分のことを処理します。Objective-C の「態度」は、厳格な強制ではなく、コミュニティの信頼の 1 つと言えるかもしれません。たとえば、私のデスクに来る人なら誰でも喜んで手伝いますが、誰かが私の持ち物をいじったり、何も言わずに動かしたりしたら、本当に腹が立ちます。適切に設計されたコードは、妄想的または反社会的である必要はありません。一緒にうまく機能する必要があります。:-)

とはいえ、インターフェースをユーザーに公開する際に必要な粒度のレベルに応じて、インターフェースを構造化するための多くのアプローチがあります。public ヘッダーで宣言するメソッドは、基本的に誰でも使用できる公正なゲームです。メソッド宣言を隠すことは、車や家に施錠するのと少し似ています — おそらく全員を締め出すことはできませんが、(1) いじってはならないことで彼らを誘惑しないことで、「正直な人々を正直に保ちます」、そして (2) ) 入ってしまった人は誰でも、入ってはいけないことを知っており、否定的な結果について文句を言うことはできません.

以下は、ファイルの命名に使用するいくつかの規則と、各ファイルに含まれるものです。下部の .m ファイルから始まり、各ファイルにはその上のファイルが含まれます。(インクルードの厳密なチェーンを使用すると、シンボルの重複警告などを防ぐことができます。) これらのレベルの一部は、Cocoa フレームワークなどのより大きな再利用可能なコンポーネントにのみ適用されます。必要に応じてそれらを調整し、自分に合った名前を使用してください。

  • MyClass.h— パブリック API (アプリケーション プログラミング インターフェイス)
  • MyClass_Private.h— 社内 SPI (システム プログラミング インターフェイス)
  • MyClass_Internal.h— プロジェクト内部 IPI (内部プログラミング インターフェイス)
  • MyClass.m— 一般に、すべての API/SPI/IPI 宣言の実装
  • MyClass_Foo.m— カテゴリなどの追加実装

API はすべての人が使用できるものであり、公的にサポートされています (通常は でFoo.framework/Headers)。SPI は、コードの内部クライアントに追加機能を公開しますが、サポートが制限される可能性があり、インターフェイスが変更される可能性があることを理解しておいてください (通常はFoo.framework/PrivateHeaders)。IPI は、プロジェクト自体の外部で使用してはならない実装固有の詳細で構成されており、これらのヘッダーはフレームワークにまったく含まれていません。SPI および IPI 呼び出しを使用することを選択した人は、自己責任で行い、通常、変更によってコードが壊れた場合に不利益を被ります。:-)

于 2009-06-19T22:32:04.620 に答える