Разница между @[] и [NSArray arrayWithObjects:]

Возможный дубликат:
Следует ли мне использовать буквальный синтаксис или конструкторы для создания словарей и массивов?

Есть ли разница между:

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

а также

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

Является ли один из них более стабильным, быстрым или чем-то еще?

3 ответа

Решение

В этой документации ничего не говорится об эффективности напрямую, но упоминается, что

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"

РЕДАКТИРОВАТЬ: Хорошо, скажем, происходит нечто подобное:) На самом деле нет другого конструктора для базовой строки.

Другие вопросы по тегам