@[] 和 [NSArray arrayWithObjects:] 之间的区别



可能的重复项:
我应该更喜欢使用文字语法还是构造函数来创建字典和数组?

两者之间有什么区别吗:

NSArray *array = @[@"foo", @"bar"];

NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", nil];

是其中之一更稳定、更快还是其他什么?

本文档没有直接提到任何关于效率的内容,但确实提到了

NSArray *array = @[@"foo", @"bar"];

相当于

NSString *strings[3];
strings[0] = @"foo";
strings[1] = @"bar";
NSArray *array = [NSArray arrayWithObjects:strings count:2];

我不得不假设在程序集级别,两者是相同的。

因此,唯一的区别是偏好。我更喜欢前者,打字更快,理解更直接。

第一个只是第二个的句法糖。它稍微好一点,因为它更短,不需要哨兵nil来标记列表的末尾。(当你使用第二个变体而忘记nil时,你可能会得到一些很好的不可预测的行为。

如果它们都不生产相同的组件,则性能差异将非常小,任何人都不会担心。这是程序集使用文字速记查找第一种情况的方式:

// NSArray *bar = @[@"bar"];
movl    %edi, -40(%ebp)
movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%esi), %eax
movl    L_OBJC_SELECTOR_REFERENCES_4-L0$pb(%esi), %edi
movl    %eax, (%esp)
movl    %edi, 4(%esp)
movl    %edx, 8(%esp)
movl    $1, 12(%esp)
movl    %ecx, -76(%ebp)         ## 4-byte Spill
calll   L_objc_msgSend$stub
movl    %eax, (%esp)
calll   L_objc_retainAutoreleasedReturnValue$stub
movl    %eax, -36(%ebp)

arrayWithObjects就是这种情况:

// NSArray *foo = [NSArray arrayWithObjects:@"foo", nil];
movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%ecx), %eax
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%ecx), %edi
movl    %eax, (%esp)
movl    %edi, 4(%esp)
movl    %edx, 8(%esp)
movl    $0, 12(%esp)
movl    %esi, -72(%ebp)         ## 4-byte Spill
calll   L_objc_msgSend$stub
movl    %eax, (%esp)
calll   L_objc_retainAutoreleasedReturnValue$stub
movl    $1, %ecx
leal    -40(%ebp), %edx
movl    -64(%ebp), %esi         ## 4-byte Reload
leal    L__unnamed_cfstring_2-L0$pb(%esi), %edi
movl    %eax, -32(%ebp)

我不知道足够的集合来得出结论,但它们看起来肯定是可比的。

这是Objective C 3.0中新发明的功能

编译器基本上将快捷方式替换为 [NSArray arrayWithObjects:...] 语句。

字符串@"String"也会发生同样的情况

编辑:好的,假设类似的事情发生在:)基本字符串实际上没有其他构造函数。

最新更新