Описание тега objective-c-literals

Clang 3.1 и Apple LLVM 4.0 представили новый литеральный синтаксис для создания объектов и индексации коллекций в Objective-C, позволяющий упростить использование NSNumber, NSArray и NSDictionary. Используйте этот тег для вопросов относительно этого синтаксиса.

Objective-C всегда имел поддержку компилятора для создания экземпляров объектов из буквенных символьных строк, так же как C позволяет создавать char * из буквальной строки. В программировании Какао (и других платформах, которые являются производными или имитируют платформы NeXTSTEP), конструкция @"Lemon curry?" в исходном коде создает NSString пример.

Clang 3.1 и компилятор Apple LLVM 4.0 представили поддержку других литеральных объектов, расширив использование @ символ для обозначения создания объекта из того, что в противном случае казалось бы примитивами. Новый синтаксис позволяет создавать NSNumbers, NSArrayс и NSDictionarys, а также "бокс" скалярных выражений (таких как enumс и BOOLс).

Для (надуманного) примера,

@[ @{ @3 : @(NSCaseInsensitiveSearch) }, @{ @"With a melon?" : @(YES) } ];

создает NSArray содержащий два NSDictionarys, первый из которых имеет пару ключ / значение NSNumber чье значение равно 3 и NSNumber значение которого является числовым значением NSCaseInsensitiveSearch, Во втором словаре есть пара, ключ которой - строка, а значение - в штучной упаковке BOOLкоторый также становится NSNumber объект.

До введения этого синтаксиса создание этих объектов было бы гораздо более громоздким:

[NSArray arrayWithObjects:[NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInteger:NSCaseInsensitiveSearch]
                                                      forKey:[NSNumber numberWithInt:3]],
                          [NSDictionary dictionaryWithObject:@"With a melon?"
                                                      forKey:[NSNumber numberWithBool:YES]], nil];

Существует важное различие, хотя и деталь реализации, между литеральными строками и этой новой литеральной поддержкой. @"Lemon curry" это пример __NSCFConstantStringчастный подкласс NSString, который создается во время компиляции и содержимое которого хранится в сегменте DATA двоичного файла программы. Напротив, буквальный синтаксис для других объектов переписывается компилятором в вызовы методов конструктора - эти объекты создаются во время выполнения, как и любой другой экземпляр их классов. (По этой причине литералы, кроме NSStrings нельзя использовать для инициализации статической или глобальной переменной.)

Также был добавлен связанный синтаксис индексации для словарей и массивов. Начиная с созданного выше массива,

NSDictionary * d = theArray[1];
NSNumber * n = d[@"With a melon?"];

результаты в n держа NSNumber представляющий логическое значение YES, Следует отметить, что эта функция индексирования требует поддержки инфраструктуры, которой нет в SDK до iOS 6 или OS X 10.8. (Компилятор не переписывает операцию индексации в objectAtIndex: а также objectForKey:, но objectAtIndexedSubscript:, а также objectForKeyedSubscript: которые не существуют в более ранних версиях Foundation.)

Однако такую ​​поддержку можно добавить довольно легко. См. Есть ли способ получить аккуратную функцию индексирования литералов Objective-C в Xcode 4.4? или ответ Аарона Хеймана на ошибку компилятора "ожидаемый метод не найден" при использовании индекса на NSArray

Полную информацию об этом синтаксисе можно найти на веб-сайте Clang: http://clang.llvm.org/docs/ObjectiveCLiterals.html