Описание тега objective-c-literals
Objective-C всегда имел поддержку компилятора для создания экземпляров объектов из буквенных символьных строк, так же как C позволяет создавать char *
из буквальной строки. В программировании Какао (и других платформах, которые являются производными или имитируют платформы NeXTSTEP), конструкция @"Lemon curry?"
в исходном коде создает NSString
пример.
Clang 3.1 и компилятор Apple LLVM 4.0 представили поддержку других литеральных объектов, расширив использование @
символ для обозначения создания объекта из того, что в противном случае казалось бы примитивами. Новый синтаксис позволяет создавать NSNumber
s, NSArray
с и NSDictionary
s, а также "бокс" скалярных выражений (таких как enum
с и BOOL
с).
Для (надуманного) примера,
@[ @{ @3 : @(NSCaseInsensitiveSearch) }, @{ @"With a melon?" : @(YES) } ];
создает NSArray
содержащий два NSDictionary
s, первый из которых имеет пару ключ / значение 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 двоичного файла программы. Напротив, буквальный синтаксис для других объектов переписывается компилятором в вызовы методов конструктора - эти объекты создаются во время выполнения, как и любой другой экземпляр их классов. (По этой причине литералы, кроме NSString
s нельзя использовать для инициализации статической или глобальной переменной.)
Также был добавлен связанный синтаксис индексации для словарей и массивов. Начиная с созданного выше массива,
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