第一个只是第二个的语法糖。它稍微好一点,因为它更短并且不需要哨兵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)
我对组装的了解不够多,无法得出结论,但它们看起来确实具有可比性。