これまでに投稿された他の回答には同意しません。ほとんどの場合、コンストラクターを使用するよりも、新しいコンテナーリテラル構文を使用する方が適切です。これらはコードの正確性に役立ち、互換性について心配することはそれほどありません。
コードの正確さ
コンテナリテラルは確かにシンタックスシュガーですが、具体的には「安全な」コンストラクタメソッド+[NSArray arrayWithObjects:count:]
とにマップされます+NSDictionary dictionaryWithObjects:forKeys:count:
。これらのメソッドのいずれかを直接使用して配列または辞書を作成するのはそれほど便利ではないため、多くのプログラマーは、を使用する方が簡単だと感じていarrayWithObjects:
ますdictionaryWithObjectsAndKeys:
。ただし、後者のメソッドには厄介な落とし穴があります。引数リストはで終了する必要があるため、オブジェクトを渡す予定の場所をnil
渡すと、予期しない配列/辞書の内容が表示される可能性があります。nil
たとえば、モデルオブジェクトの1つのプロパティをマッピングするディクショナリを設定しているとします(おそらく、JSONとして送信しますか?):
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
person.name, @"name", person.title, @"title", person.address, @"address",
nil];
このコードがPerson
notitle
が設定されているに遭遇した場合、結果の辞書には@"address"
キーとその値がありません。データベース内の一部の人がアドレスを失っている理由を追跡するのに何時間も費やすことができます(そして、上記のコードを見て、なぜそれが機能しないのか疑問に思って髪を引き裂いてください、私はそれをすぐに設定しています!)。私たちの多くは持っています。
対照的に、次のような文字通りの形式を使用する場合:
NSDictionary *dictionary = @{
@"name": person.name, @"title": person.title, @"address": person.address };
これは次のように拡張されます。
id objects[] = { person.name, person.title, person.address };
id keys[] = { @"name", @"title", @"address" };
NSUInteger count = sizeof(objects) / sizeof(keys);
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
forKeys:keys
count:count];
また、またはがを返す場合person.name
、person.title
このnil
メソッドは、不要なデータをサイレントに作成する代わりに、例外をスローします。(どちらの方法でも、コードでnil
タイトルを処理する方法を決定する必要がありますが、この方法で問題をより早く見つけることができます。)そして確かに、同等の構文糖衣を使用する代わりに、この「より安全な」フォームを自分で書くことができます。しかしdictionaryWithObjectsAndKeys:
、それが短いので、あなたはただ書く習慣に頼らないと確信していますか?
互換性
コンテナリテラル(さらに言えば、数値リテラルとボックス式)によって生成されたコードは新しいAPIを使用しないため、Xcode 4.4以降(またはClang 3.1以降)でコンパイルして、任意のバージョンのFoundationにデプロイできます。ただし、ソースコードが古いコンパイラやGNUStepでも使用される場合は、互換性を考慮する必要があります。(GNUStepはClangでもうまくいくように聞こえますが。)
そして、それは質問の一部ではありませんが、関連する主題に関するものであるため、新しいオブジェクトの添え字構文についても同じことが「一種の」真実です。これは、Mac OS X10.6およびiOS6.0でのみ定義されている新しいメソッドを使用します...しかし、これらのメソッドはによって提供されlibarclite
ます。(ご存知のとおり、ARCコードをiOS4.3またはMacOS X 10.6にデプロイしようとするとリンクされるライブラリ-もはやARCだけではありません!)したがって、必要なのはヘッダーでそれらを宣言することだけです。まだ行っていない場合はARCLiteを使用して、問題ありません。