Difference between @[] and [NSArray arrayWithObjects:] [duplicate]
Asked Answered
N

3

8

Possible Duplicate:
Should I prefer to use literal syntax or constructors for creating dictionaries and arrays?

Is there any difference between:

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

and

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

Is one of those more stable, faster, or anything else?

Niemann answered 11/10, 2012 at 7:37 Comment(0)
D
11

This documentation doesn't mention anything about efficiency directly, but does mention that

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

is equivalent to

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

I would have to assume that at an assembly level, the two are identical.

Thus the only difference is preference. I prefer the former, it's faster to type and more direct to understand.

Dymphia answered 11/10, 2012 at 7:47 Comment(0)
B
6

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.

Bdellium answered 11/10, 2012 at 7:47 Comment(3)
Try [NSArray arrayWithObject:@"bar"]; This should be the same as @[@"bar"];Synchronize
Bugger, at W3C they said the compiler would interpret this the same.Synchronize
+1 For the assembly translation.Stidham
S
0

This is a feature new invented in Objective C 3.0

The compiler basically replaces the shortcut with a [NSArray arrayWithObjects:...] statement.

The same happens with Strings @"String"

EDIT: Ok, let's say something similar happens :) There actually is no other constructor for a basic string.

Synchronize answered 11/10, 2012 at 7:49 Comment(1)
The string case is different, actually. There's no conversion to a constructor method; the object is a static part of the binary.Merrileemerrili

© 2022 - 2024 — McMap. All rights reserved.