Разница между @[] и [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"
РЕДАКТИРОВАТЬ: Хорошо, скажем, происходит нечто подобное:) На самом деле нет другого конструктора для базовой строки.