The first is just a syntactic sugar for the second. It’s slightly better because it’s shorter and doesn’t require the sentinel nil
to mark the end of the list. (When you use the second variant and forget the nil
, you can get some nicely unpredictable behaviour.)
If they both do not produce the same assembly, the performance difference is going to be so small it’s not of concern for anybody. This is how the assembly looks for the first case with literal shorthand:
// 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)
And this is the case with 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)
I don’t know enough assembly to make conclusions, but they certainly look comparable.