Есть ли буквальный словарь или синтаксис массива в Objective-C? - PullRequest
39 голосов
/ 14 марта 2012

Всегда можно было создать NSArrays (и NSDictionaries / NSNumber) с вызовами методов vararg, например:

[NSArray arrayWithObjects: @"a", @"b", @"c", nil];

Можно ли их создавать с помощью встроенных литералов в новом улучшении LLVM и Clang?

Ответы [ 2 ]

95 голосов
/ 14 марта 2012

С помощью этого изменения в кодовой базе 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).

5 голосов
/ 14 марта 2012
NSNumber *intNumber1 = @42;
NSArray *array1 = @[@"foo", @42, @"bar", @3.14];
NSDictionary *dictionary1 = @{ @1: @"red", @2: @"green", @3: @"blue" };

Источник: http://blog.ablepear.com/2012/02/something-wonderful-new-objective-c.html

...