Difference between @[] and [NSArray arrayWithObjec

2019-04-25 12:20发布

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?

3条回答
Ridiculous、
2楼-- · 2019-04-25 12:30

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.

查看更多
地球回转人心会变
3楼-- · 2019-04-25 12:35

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.

查看更多
冷血范
4楼-- · 2019-04-25 12:36

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.

查看更多
登录 后发表回答