web-dev-qa-db-fra.com

Existe-t-il un dictionnaire littéral ou une syntaxe de tableau dans Objective-C?

Il a toujours été possible de créer des NSArrays (et NSDictionaries/NSNumber) avec des appels de méthode vararg, comme:

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

Peut-on les créer avec des littéraux en ligne dans une nouvelle amélioration de LLVM et Clang?

42
AlBlue

Avec ce changement à la base de code LLVM, Apple a ajouté une nouvelle syntaxe pour les littéraux dans les prochaines versions du compilateur Clang.

Auparavant, les tableaux étaient créés à l'aide d'un tableau basé sur C et étaient convertis à la volée en objets Objective-C, tels que:

NSArray* array = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];

Notez que comme il s'agit d'un élément varargs, vous devez fournir une fin "nil" à la fin de la liste. Cependant, il existe maintenant un moyen plus simple:

NSArray* array = @[ @"One", @"Two", @"Three" ];

Notez que le premier @ avant le [] est requis, pour le distinguer d'un tableau C ordinaire (ou d'un message envoyé). Notez également que le "zéro" de fin n'est plus requis.

Une modification similaire a été apportée aux littéraux de dictionnaire en ligne, similaire aux structures JSON:

NSDictionary* dict = @{
    @"Key1": @"Value1",
    @"Key2": @"Value2",
};

Enfin, un nouveau littéral pour NSInteger (etc.) a été ajouté:

NSNumber* value = @3.141;

Notez que bien que cela fonctionne pour les virgules flottantes (@3.141F) Et les doubles (@3.141), Cela ne fonctionne pas pour long double S car ceux-ci ne sont pas pris en charge pour l'encapsulation par le compilateur. Ainsi, @3.141D Sera une erreur de compilation.

En raison de la façon dont les constantes sont définies, @INT_MAX Est une valeur valide valide mais pas @INT_MIN, Car cette dernière est définie via une expression au moment de la compilation et non un littéral en soi.

Il existe également des extensions aux types booléens:

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]

Cette modification a également introduit les littéraux __objc_yes Et __objc_no Pour prendre en charge l'analyse des types via la valeur littérale uniquement. Leur utilisation est protégée par #if __has_feature(objc_bool) dans le préprocesseur, mais les développeurs doivent continuer à utiliser YES et NO dans le code.

Enfin, les tableaux et les dictionnaires peuvent désormais être indexés avec des crochets de tableau, utilisés à la fois comme expressions lvalue et rvalue:

NSMutableArray* stuff = ...
id first = stuff[0];
stuff[0] = anotherObject;

NSMutableDictionary* moreStuff = ...
id conference = moreStuff[@"NSConf"]
moreStuff[@"SponsoredBy"] = @"NSConfDuck"

L'indexation de style de tableau (à l'aide d'un NSUInteger) est mappée sur objectAtIndexedSubscript: Et le setObject:atIndexedSubscript: Correspondant, tandis que l'accès au dictionnaire est accessible avec objectForKeyedSubscript: Et setObject:forKeyedSubscript:

La syntaxe complète des littéraux peut être consultée sur le site Web de Clang/LLVM

Notez que depuis que cette réponse a été initialement écrite, Clang a ajouté la prise en charge des expressions Objective-C non littérales appelées "expressions encadrées"

Cela signifie que l'on peut utiliser @(3+4) comme équivalent à @7, Et @("Hello World") comme @"Hello World". Notez qu'une expression C qui évalue à null entraînera une exception et les arguments tels que @(null) sont traités comme une erreur de compilation.

Il est également possible d’utiliser des "énumérations encadrées" pour les types dont le type est connu.

enum {Nord, Sud, Est, Ouest,};

peut être placé dans un type énuméré encadré avec @(North), qui aura la valeur 0.

Les expressions encadrées seront disponibles à partir de la version 3.2. Il peut être testé pour utiliser le test de préprocesseur __has_feature(objc_boxed_expressions).

97
AlBlue
NSNumber *intNumber1 = @42;
NSArray *array1 = @[@"foo", @42, @"bar", @3.14];
NSDictionary *dictionary1 = @{ @1: @"red", @2: @"green", @3: @"blue" };

Source: http://blog.ablepear.com/2012/02/something-wonderful-new-objective-c.html

5
joerick