12

ココアでの列挙型宣言のさまざまなスタイルの背後にある理論的根拠は何だろうと思っていましたか?

このような:

enum { constants.. }; typedef NSUInteger sometype;

typedef を使用して NSUInteger への代入をキャストせずに機能させる理由は何ですか?

typedef が NSInteger/NSUInteger のいずれかである場合がありますが、常に NSInteger を使用しないのはなぜですか? NSUInteger を使用するメリットはありますか?

_NSByteOrderのように、列挙タグ名はまだ時々使用されます。

この回答も非常に役に立ちました: What is a typedef enum in Objective-C? .

4

3 に答える 3

12

いくつかの理由:

理由 1: 柔軟性:

enum lickahoctor { yes = 0, no = 1, maybe = 2 };

列挙を宣言します。値 と を任意のyes場所nomaybe使用して、任意の整数型に割り当てることができます。これを型として使用することもできます。

enum lickahoctor myVar = yes;

関数が enum lickahoctor 型のパラメーターを受け取る場合yesnoまたはmaybeを割り当てることができることがわかるため、これは便利です。また、デバッガーはそれを認識するため、数値の代わりに記号名を表示します。enum lickahoctor問題は、コンパイラが に定義した値しか代入できないことですmyVar。たとえば、基本クラスでいくつかのフラグを定義し、サブクラスでさらにいくつかのフラグを追加する場合、この方法では実行できません。

代わりに int を使用すると、その問題は発生しません。したがって、ある種の int を使用したいので、任意の定数を割り当てることができます。

理由 2: バイナリ互換性:

コンパイラは、列挙型で定義したすべての定数に適合する適切なサイズを選択します。何が得られる保証はありません。そのため、そのような変数を含む構造体をファイルに直接書き込んだ場合、アプリの次のバージョンで再度読み込んだときに同じサイズであるという保証はありません (少なくとも C 標準によれば、 -実際にはそれほど暗くはありません)。

代わりにある種の int を使用すると、プラットフォームは通常、その数値に対して特定のサイズを保証します。特に、int32_t/のように、特定のサイズであることが保証されているタイプのいずれかを使用する場合uint32_t

理由 3: 読みやすさと自己文書化

上で myVar を宣言すると、どのような値を入れることができるかがすぐにわかります。int または のみを使用する場合はuint32_t、そうではありません。だからあなたがすることはあなたが使うことです

enum { yes, no, maybe };
typedef uint32_t lickahoctor;

このタイプの変数がこの値を保持できることを人々に思い出させるために、定数の近くのどこかに整数の素敵な名前を定義します。ただし、予測可能な固定サイズと、必要に応じてサブクラスで追加の値を定義する機能の利点は引き続き得られます。

理由 4: ビットフィールドのサポート

列挙型の変数は、オプションから正確に 1 つの値の割り当てのみをサポートします。したがって、ビット フィールドを実装しようとしている場合、それをビットフィールドとして入力することはできません。さらに、符号拡張があなたを台無しにするのを避けるために、符号なし変数を使用する必要があります。

于 2010-02-12T20:42:14.743 に答える
2

typedef を使用して NSUInteger への代入をキャストせずに機能させる理由は何ですか?

typedef は、列挙値の基本型を指定するために使用されます。NSUIntegerより小さい型 ( to )にキャストすることにより、値を切り捨てる限り、いつでも列挙値を別の型にキャストできますunsigned short

NSInteger符号付き整数とNSUInteger符号なし整数の両方にアーキテクチャ/プラットフォームに依存しない型を提供することで、アプリケーションの 64 ビット移行を容易にするために導入されました。これにより、CPU のビット数に関係なく、アプリケーションを書き換える必要がなくなります。

typedef が NSInteger/NSUInteger のいずれかである場合がありますが、常に NSInteger を使用しないのはなぜですか? NSUInteger を使用するメリットはありますか?

選択は、列挙の値によって異なります。一部の列挙には多くの値があるため、利用可能なすべてのビットが必要です。

  • NSInteger は、2^31 の正と負の値を提供します (32 ビット アーキテクチャ上)。
  • NSUInteger は 2^32 の正の値を提供します (32 ビット アーキテクチャ上)。
  • 列挙に正の値のみを含めることを意図している場合は、NSUInteger を使用してください。
  • 列挙に正の値と負の値の両方を含めることを意図している場合は、NSInteger を使用してください。
  • NSUInteger は通常、フラグの列挙に使用されます。これは、自由に組み合わせることができる 32 個の個別の値 (32 ビット アーキテクチャ上) を提供するためです。

Apple 開発チームにそのための選択規則があるかどうかはわかりません。そうだといい...

于 2010-02-12T10:21:32.533 に答える
1

あなたは次のようなものを使うことができますが

  typedef enum { constants... } sometype;

データ型の最終的なビットサイズについて保証はありません。まあ、それは厳密には真実ではありませんが、十分に真実です。API は、使用するコンパイラの設定に応じて変化するものよりも、具体的なデータ サイズで定義する方が適切です。

于 2010-02-11T22:30:20.543 に答える