我不同意迄今为止发布的其他答案:几乎所有时候,使用新的容器文字语法比使用构造函数更好。它们有助于代码的正确性,而且对于兼容性并没有太多担心。
代码正确性
容器文字确实是语法糖,但特别是它们映射到“安全”构造函数方法+[NSArray arrayWithObjects:count:]
和+NSDictionary dictionaryWithObjects:forKeys:count:
. 直接使用其中一种方法构造数组或字典并不是那么方便,因此许多程序员发现使用arrayWithObjects:
and更简单dictionaryWithObjectsAndKeys:
。但是,后一种方法有一个令人讨厌的缺陷:由于参数列表必须以 终止nil
,如果您通过nil
您打算传递对象的位置,您会发现自己有意想不到的数组/字典内容。
例如,假设您正在设置一个映射您的模型对象之一的属性的字典(也许您要将其作为 JSON 发送?):
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
person.name, @"name", person.title, @"title", person.address, @"address",
nil];
如果此代码遇到已设置Person
no的对象title
,则生成的字典将缺少@"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 X 10.6 和 iOS 6.0 上定义的新方法……但这些方法由libarclite
. (你知道,当你尝试将 ARC 代码部署回 iOS 4.3 或 Mac OS X 10.6 时,链接的库——它不再只是用于 ARC!)所以你需要做的就是在标题中声明它们,链接如果您还没有 ARCLite,那么您就可以开始了。