С помощью этого изменения в кодовой базе LLVM Apple добавила новый синтаксис для литералов в следующих версиях компилятора Clang.
Ранее массивы создавались с использованием массива на основе C и преобразовывались на лету в объекты Objective-C, такие как:
NSArray* array = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
Обратите внимание, что, поскольку это элемент varargs, вы должны были поставить окончание 'nil' в конце списка. Однако теперь есть более простой способ:
NSArray* array = @[ @"One", @"Two", @"Three" ];
Обратите внимание, что требуется начальный @ перед [], чтобы различать его и обычный массив C (или отправку сообщения). Также обратите внимание, что завершающий ноль больше не требуется.
Аналогичное изменение было внесено для литералов встроенного словаря, аналогично структурам JSON:
NSDictionary* dict = @{
@"Key1": @"Value1",
@"Key2": @"Value2",
};
Наконец, был добавлен новый литерал для NSInteger (и т. Д.):
NSNumber* value = @3.141;
Обратите внимание, что хотя это работает для чисел с плавающей запятой (@3.141F
) и удваивается (@3.141
), оно не работает для long double
с, поскольку они не поддерживаются для переноса компилятором. Таким образом, @3.141D
будет ошибкой во время компиляции.
Вследствие того, как определены константы, @INT_MAX
является действительным допустимым значением, а @INT_MIN
- нет, поскольку последнее определяется с помощью выражения времени компиляции, а не литерала сам по себе.
Существуют также расширения для логических типов:
NSNumber* yes = @YES; // [NSNumber numberWithBool:YES]
NSNumber* no = @NO; // [NSNumber numberWithBool:NO]
NSNumber* trueBool = @true; // [NSNumber numberWithBool:(BOOL)true]
NSNumber* falseBool = @false; // [NSNumber numberWithBool:(BOOL)false]
Это изменение также ввело литералы __objc_yes
и __objc_no
для поддержки анализа типов только через литеральные значения. Их использование защищено #if __has_feature(objc_bool)
в препроцессоре, но разработчики должны продолжать использовать YES
и NO
в коде.
Наконец, массивы и словари теперь могут быть подписаны с помощью скобок массива, которые используются как выражения lvalue
и rvalue
:
NSMutableArray* stuff = ...
id first = stuff[0];
stuff[0] = anotherObject;
NSMutableDictionary* moreStuff = ...
id conference = moreStuff[@"NSConf"]
moreStuff[@"SponsoredBy"] = @"NSConfDuck"
Подписка стиля массива (с использованием NSUInteger
) сопоставляется с objectAtIndexedSubscript:
и соответствующим setObject:atIndexedSubscript:
, в то время как доступ к словарю осуществляется с помощью objectForKeyedSubscript:
и setObject:forKeyedSubscript:
Полный синтаксис для литералов можно увидеть на сайте Clang / LLVM
Обратите внимание, что с тех пор, как этот ответ был изначально написан, Clang добавил поддержку не-буквальных выражений Objective-C, называемых «выражениями в штучной упаковке»
Это означает, что можно использовать @(3+4)
как эквивалент @7
и @("Hello World")
как @"Hello World"
. Обратите внимание, что выражение C, которое оценивается как null
, приведет к исключению, а такие аргументы, как @(null)
, обрабатываются как ошибка времени компиляции.
Также можно использовать 'перечислимые в штучной упаковке' для типов с известным типом, поэтому
enum {
К северу,
Юг,
Восток,
Запад,
};
может быть помещен в упакованный тип enum с @(North)
, который будет иметь значение 0
.
Выражения в штучной упаковке будут доступны в clang 3.2 и далее. Его можно протестировать на использование препроцессорного теста __has_feature(objc_boxed_expressions)
.