39

tl;dr バージョン

したがって、列挙型を宣言するときに、列挙型の定数のデータ型が unsigned int ではなく NSUInteger であることが保証される方法は次のとおりです。

enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};
typedef NSUInteger NSCellType;

NSUInteger への typedef は、enum 宣言に結び付けられているようには見えません。

完全版

列挙値に関するいくつかのガイダンスについて、Apple の64-Bit Transition Guide for Cocoaを読んでいたところ、疑問が生じました。これは、列挙定数セクションからの(長い)引用です。

列挙 (enum) 定数の問題は、そのデータ型が不確定であることが多いことです。言い換えれば、列挙型定数は unsigned int であるとは限りません。従来の方法で構築された列挙型では、コンパイラは実際に検出したものに基づいて基になる型を設定します。基になる型は (符号付き) int または long にすることができます。次の例を見てください。

type enum {
    MyFlagError = -1,
    MyFlagLow = 0,
    MyFlagMiddle = 1,
    MyFlagHigh = 2
} MyFlagType;

コンパイラはこの宣言を調べ、メンバ定数の 1 つに割り当てられた負の値を見つけて、列挙型 int の基になる型を宣言します。メンバーの値の範囲が int または unsigned int に収まらない場合、基本型は暗黙のうちに 64 ビット (long) になります。したがって、列挙型として定義された量の基本型は、列挙型の値に合わせてサイズをサイレントに変更できます。これは、32 ビットまたは 64 ビットのどちらでコンパイルしているかに関係なく発生する可能性があります。言うまでもなく、この状況はバイナリ互換性にとって障害となります。

この問題の解決策として、Apple は Cocoa API の列挙型についてより明確にすることを決定しました。列挙型に関して引数を宣言する代わりに、ヘッダー ファイルは、サイズを指定できる列挙型の型を個別に宣言するようになりました。列挙のメンバーとその値は、以前と同様に宣言され、割り当てられます。たとえば、これの代わりに:

typedef enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
} NSCellType;

これがあります:

enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};
typedef NSUInteger NSCellType;

列挙型は、NSInteger または NSUInteger に関して定義され、基本列挙型を 64 ビット アーキテクチャで 64 ビット対応にします。

私の質問は次のとおりです: typedef が enum 宣言に明示的に関連付けられていないように見える場合、データ型が unsigned int か NSUInteger かをどうやって知ることができますか?

4

4 に答える 4

53

NS_ENUMXcode 4.5が開始されました。

typedef NS_ENUM(NSUInteger, NSCellType) {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};

NS_OPTIONSまた、バイナリ フラグを使用するかどうかを検討できます。

typedef NS_OPTIONS(NSUInteger, MyCellFlag) {
    MyTextCellFlag = 1 << 0,
    MyImageCellFlag = 1 << 1,
};
于 2012-11-13T12:33:43.683 に答える
8

これらは2つの別々の宣言です。typedefは、その型を使用するときに、常にNSUIntegerを取得することを保証します。

列挙型の問題は、値を保持するのに十分な大きさではないということではありません。実際、列挙型に対して得られる唯一の保証は、sizeof(enum Foo)が、その列挙型で現在定義している値を保持するのに十分な大きさであるということです。ただし、別の定数を追加すると、サイズが変わる可能性があります。そのため、AppleはAPIのバイナリの安定性を維持するために、個別のtypedefを実行します。

于 2011-12-13T22:19:33.273 に答える