7

Clangのプリミティブボクシング機能を使用して列挙型メンバーをにパックしていますNSNumber

これに関するClangドキュメントのBoxedEnumsセクションでは、型が指定されていない限り、コンパイラーは列挙型メンバーを整数にボックス化すると述べています。

おかしなことに、列挙型メンバーをメソッドに渡す方法に応じて、さまざまなサイズの整数を取得します。私は次のコードにケースを分離することができました

typedef enum _MyEnum {
    MyEnumMember1 = 1000
} MyEnum;

- (void)testEnumerationBoxing
{
    NSNumber *numberA = [self testA];
    NSNumber *numberB = [self testB:MyEnumMember1];

    CFNumberType numberTypeA = CFNumberGetType((__bridge CFNumberRef) numberA);
    CFNumberType numberTypeB = CFNumberGetType((__bridge CFNumberRef) numberB);
    NSLog(@"CF Number type for A: %lu; B: %lu", numberTypeA, numberTypeB);
}

- (NSNumber *)testA
{
    return @(MyEnumMember1);
}

- (NSNumber *)testB:(MyEnum)enumMember
{
    return @(enumMember);
}

コンソール出力は

AのCF番号タイプ:3; B:4

(最初のものはkCFNumberSInt32Type、2番目のものはですkCFNumberSInt64Type

宣言をに変更するtypedef enum _MyEnum : intと、両方で同じ結果が表示されますkCFNumberSInt32Type

ボクシングの2つの方法で整数のサイズが異なるのはなぜですか?

4

2 に答える 2

4

私はこのケースがあなたが提供したリンクで説明されていると思います:

列挙型の値をボックス化すると、列挙型の基になる型に応じた作成メソッドを持つNSNumberポインターが生成されます。これは、固定の基になる型、またはコンパイラー定義の整数型で、列挙:

typedef enum : unsigned char { Red, Green, Blue } Color;
Color col => Red;
NSNumber *nsCol = @(col); // => [NSNumber numberWithUnsignedChar:]

しかし、図書館でのプロモーションの詳細はカバーされておらず、そこで期待の違いが紹介されています。

-testA呼び出してしまう+[NSNumber numberWithInt:]

-testB呼び出してしまう+[NSNumber numberWithUnsignedInt:]

したがって、表示される抽象化された「プロモーション」は、現時点ではCFNumber(したがってNSNumber)実際には符号なしの値をサポートしていないためです(CFNumberType列挙型の定数を参照)-表示されている出力に基づいて、NSNumber実装は単に次の符号付きに昇格すると想定されますコンストラクターの符号なし初期化子の場合にすべての値を表すことができる型-明らかに、値をテストして「幅の最小化」を適用できるかどうかを確認する必要はありません。

もちろん、NSNumber符号なし型をパラメーターとして受け取るコンストラクターと初期化子を宣言しますが、符号なし整数の内部表現は、実際には符号付き整数表現として格納されます。

ボックス化されたリテラルをにプロモートするときに、コンパイラは適切/正確なコンビニエンスコンストラクタを呼び出すように見えますNSNumber。たとえば、uint16_t型指定された列挙型は32ビットint(via)として格納されnumberWithUnsignedShort:、int32_tも32ビットint(via numberWithInt:)です。ただし、-testA値の場合も既知であるため、より適切なコンストラクターを呼び出すこともできます。したがって、コンパイラーは、型と値ではなく、型に基づいて幅を最小化するだけです。列挙型のタイプが指定されていないか、符号なしタイプとして指定されている場合、このようなプロモーションが表示されることがあります。

于 2012-08-24T18:49:56.477 に答える
1

列挙(enum)定数の問題は、それらのデータ型が頻繁に不確定になることです。言い換えると、列挙型定数は予想通りunsignedintではありません。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Cocoa64BitGuide/64BitChangesCocoa/64BitChangesCocoa.htmlをご覧ください

これがお役に立てば幸いです。

于 2012-08-24T15:37:36.413 に答える