web-dev-qa-db-ja.com

Objective-Cにリテラル辞書または配列構文はありますか?

次のように、varargメソッドを呼び出してNSArray(およびNSDictionaries/NSNumber)を作成することは常に可能です。

[NSArray arrayWithObjects: @"a", @"b", @"c", nil];

これらは、LLVMとClangの新しい改善点でインラインリテラルを使用して作成できますか?

42
AlBlue

この変更 をLLVMコードベースに追加すると、Appleは、Clangコンパイラの今後のバージョンでリテラルの新しい構文を追加しました。

以前は、配列はCベースの配列を使用して作成され、次のようなObjective-Cオブジェクトにその場で変換されました。

_NSArray* array = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
_

これはvarargs要素であるため、リストの最後に「nil」で終了する必要があることに注意してください。しかし、今はもっと簡単な方法があります:

_NSArray* array = @[ @"One", @"Two", @"Three" ];
_

[]と通常のC配列(またはメッセージ送信)を区別するために、[]の前の@が必要であることに注意してください。また、末尾の「nil」は不要になったことにも注意してください。

JSON構造と同様に、インライン辞書リテラルにも同様の変更が加えられました。

_NSDictionary* dict = @{
    @"Key1": @"Value1",
    @"Key2": @"Value2",
};
_

最後に、NSInteger(など)の新しいリテラルが追加されました。

_NSNumber* value = @3.141;
_

これは浮動小数点(_@3.141F_)および倍精度浮動小数点数(_@3.141_)には機能しますが、_long double_ sには機能しません。これらはコンパイラーによるラップがサポートされていないためです。したがって、_@3.141D_はコンパイル時エラーになります。

定数の定義方法により、_@INT_MAX_は有効な有効な値ですが、_@INT_MIN_は有効ではありません。後者はコンパイル時の式によって定義され、それ自体はリテラルではないためです。

ブール型への拡張もあります:

_NSNumber* yes = @YES;         // [NSNumber numberWithBool:YES]
NSNumber* no = @NO;           // [NSNumber numberWithBool:NO]
NSNumber* trueBool = @true;   // [NSNumber numberWithBool:(BOOL)true]
NSNumber* falseBool = @false; // [NSNumber numberWithBool:(BOOL)false]
_

この変更により、___objc_yes_および___objc_no_リテラルも導入され、リテラル値のみによる型の解析がサポートされました。それらの使用はプリプロセッサの#if __has_feature(objc_bool)で保護されていますが、開発者はコードでYESNOを引き続き使用する必要があります。

最後に、配列と辞書の両方にlvaluervalue式の両方として使用する場合に、配列括弧で添え字を付けることができます。

_NSMutableArray* stuff = ...
id first = stuff[0];
stuff[0] = anotherObject;

NSMutableDictionary* moreStuff = ...
id conference = moreStuff[@"NSConf"]
moreStuff[@"SponsoredBy"] = @"NSConfDuck"
_

配列スタイルの添え字(NSUIntegerを使用)は_objectAtIndexedSubscript:_および対応する_setObject:atIndexedSubscript:_にマップされますが、辞書アクセスは_objectForKeyedSubscript:_および_setObject:forKeyedSubscript:_でアクセスされます。

リテラルの完全な構文は、 Clang/LLVM Webサイト で確認できます。

この回答は最初に書かれて以来、Clangは「ボックス化された式」と呼ばれる非リテラルObjective-C式のサポートを追加していることに注意してください

これは、@(3+4)を_@7_と同等に使用し、@("Hello World")を_@"Hello World"_として使用できることを意味します。 nullと評価されるC式は例外となり、@(null)などの引数はコンパイル時エラーとして扱われます。

既知のタイプのタイプに「ボックス化列挙型」を使用することもできるため、

列挙型{North、South、East、West、};

@(North)でボックス化された列挙型に配置でき、値は_0_になります。

ボックス化された式は、clang 3.2以降で使用できます。 __has_feature(objc_boxed_expressions)プリプロセッサテストを使用してテストできます。

97
AlBlue
NSNumber *intNumber1 = @42;
NSArray *array1 = @[@"foo", @42, @"bar", @3.14];
NSDictionary *dictionary1 = @{ @1: @"red", @2: @"green", @3: @"blue" };

ソース: http://blog.ablepear.com/2012/02/something-wonderful-new-objective-c.html

5
joerick