web-dev-qa-db-fra.com

Quels sont les détails des "Littéraux Objective-C" mentionnés dans les notes de publication de Xcode 4.4?

Je parcourais les notes de publication pour Xcode 4.4 et j'ai remarqué ceci:

Compilateur LLVM 4.0

Xcode inclut désormais le Apple LLVM Compiler version 4.0, y compris les nouvelles fonctionnalités du langage newObjective-C: [...]
- Littéraux Objective-C: créez des littéraux pour NSArray, NSDictionary et NSNumber, de la même manière que les littéraux de NSString

Je suis intrigué par cette fonctionnalité. Je ne comprends pas très bien comment les littéraux de NSString fonctionnent et comment on peut les utiliser sur NSArray, NSDictionary et NSNumber.

Quels sont les détails?

188
Pedro Mancheno

Copié textuellement de http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and :

Littéraux Objective-C: On peut maintenant créer des littéraux pour NSArray, NSDictionary et NSNumber (seulement comme on peut créer des littéraux pour NSString)

Littéraux NSArray

Précédemment:

array = [NSArray arrayWithObjects:a, b, c, nil];

Maintenant:

array = @[ a, b, c ];

Littéraux NSDictionary

Précédemment:

dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3]
                                   forKeys:@[k1, k2, k3]];

Maintenant:

dict = @{ k1 : o1, k2 : o2, k3 : o3 };

NSNumber Literals

Précédemment:

NSNumber *number;
number = [NSNumber numberWithChar:'X'];
number = [NSNumber numberWithInt:12345];
number = [NSNumber numberWithUnsignedLong:12345ul];
number = [NSNumber numberWithLongLong:12345ll];
number = [NSNumber numberWithFloat:123.45f];
number = [NSNumber numberWithDouble:123.45];
number = [NSNumber numberWithBool:YES];

Maintenant:

NSNumber *number;
number = @'X';
number = @12345;
number = @12345ul;
number = @12345ll;
number = @123.45f;
number = @123.45;
number = @YES;

[Modifier]

zxoq sur http://news.ycombinator.com/item?id=3672744 a ajouté un nouvel indice plus intéressant. (Ajouté avec littéraux):

arr[1]      === [arr objectAtIndex:1]
dict[@"key"] === [dict objectForKey:@"key"]

[Modifier 2]

Les nouveaux littéraux ObjC ont été discutés dans plusieurs sessions WWDC 2012 . J'ai volontairement pas supprimé les noms de fichiers et l'heure de chaque diapositive afin que vous puissiez les trouver vous-même si vous en avez envie. C’est essentiellement la même chose que ce qui est dit dans ce billet, mais il y a quelques nouvelles choses que je mentionnerai au-dessus des images.

Veuillez noter que les images sont toutes grandes. Il suffit de les faire glisser dans un autre onglet pour les afficher dans leur taille originale

Literals & Boxing

[NSNumber numberWithint:42]
[NSNumber numberWithDouble:10.8]
[NSNumber numberWithBool:YES]
[NSNumber numberWithint:6 + x * 2012]

Literals & Boxing

@42
@10.8
@YES
@(6 + x * 2012)

Collection Subscripting

[NSArray arrayWithObjects: a, b, c, nil]
[array objectAtIndex:i]
[NSDictionary dictionaryWithObjectsAndKeys: v1, k1, v2, k2, nil];
[dictionary valueForKey:k]

Collection Subscripting

@[a, b, c]
array[i]
@{k1:v1, k2:v2}
dictionary[k]

@# numbers, @{} dictionaries, @"" strings, @[] arrays, @() expressions


Cette partie est nouvelle. Littéraux d'expression

Quand vous avez une expression (M_PI / 16 _ par exemple) vous devriez le mettre entre parenthèses.

Cette syntaxe fonctionne pour les expressions numériques, les booléens, la recherche d'un index dans une chaîne (C-), les valeurs booléennes, les constantes enum et même les chaînes de caractères!

Expression Literals

NSNumber *piOverSixteen = [NSNumber numberWithDouble: (M_PI / 16)];

NSNumber *hexDigit = [NSNumber numberWithChar:"0123456789ABCDEF"[i % 16]];

NSNumber *usesScreenFonts = [NSNumber numberWithBool:[NSLayoutManager usesScreenFonts]];

NSNumber *writingDirection = [NSNumber numberWithInt:NSWritingDirectionLeftToRight];

NSNumber *path = [NSString stringWithUTF8String: getenv("PATH")];

Expression Literals

NSNumber *piOverSixteen = @( M_PI / 16 );

NSNumber *hexDigit = @( "0123456789ABCDEF"[i % 16] );

NSNumber *usesScreenFonts = @( [NSLayoutManager usesScreenFonts] );

NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );

NSNumber *path = @( getenv("PATH") );

En savoir plus sur les chaînes de caractères et comment/quand utiliser cette syntaxe littérale:

Boxed String Expressions

NSString *path = [NSString stringWithUTF8String: getenv("PATH")];
for (NSString *dir in [path componentsSeparatedByString: @":"]) {
    // search for a file in dir...
}

Boxed String Expressions

NSString *path = @( getenv("PATH") );
for (NSString *dir in [path componentsSeparatedByString: @":"]) {
    // search for a file in dir...
}

Comment fonctionnent les littéraux de tableaux

How array literals work

// when you write this:
array = @[a, b, c ];

// compiler generates:
id objects[] = { a, b, c };
NSUInteger count = sizeof(objects) / sizeof(id);
array = [NSArray arrayWithObjects:objects count:count];

Comment fonctionnent les littéraux de dictionnaire

How dictionary literals work

// when you write this:
dict = @{k1 : o1, k2 : o2, k3 : o3 };

// compiler generates:
id objects[] = { o1, o2, o3 };
id keys[] = { k1, k2, k3 };
NSUInteger count = sizeof(objects) / sizeof(id);
dict = [NSDictionary dictionaryWithObjects:objects
                                   forKeys:keys
                                     count:count];

Plus sur les indices de tableau

Array Subscripting

@implementation SongList {
    NSMutableArray *_songs;
}

- (Song *)replaceSong:(Song *)newSong atindex:(NSUinteger)idx {
    Song *oldSong = [_songs objectAtIndex:idx];
    [_songs replaceObjectAtindex:idx withObject:newSong];
    return oldSong;
}

Array Subscripting

@implementation SongList {
    NSMutableArray *_songs;
}

- (Song *)replaceSong:(Song *)newSong atindex:(NSUinteger)idx {
    Song *oldSong = _songs[idx];
    _songs[idx] = newSong;
    return oldSong;
}    

Plus sur la souscription au dictionnaire

Dictionary Subscripting

@implementation Database {
    NSMutableDictionary *_storage;
}

- (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key {
    id oldObject = [_storage objectForKey:key];
    [_storage setObject:object forKey:key];
    return oldObject;
}

Dictionary Subscripting

@implementation Database {
    NSMutableDictionary *_storage;
}

- (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key {
    id oldObject = _storage[key];
    _storage[key] = newObject;
    return oldObject;
}

[Edit 3]

Mike Ash a un excellent article sur ces nouveaux littéraux. Si vous voulez en savoir plus sur ce sujet, assurez-vous de vérifiez-le .


393
Pooria Azimi

Le compilateur Objective-C a une connaissance codée en dur de la disposition de la mémoire des instances de la classe NSConstantString, autrement dit de la classe __CFConstantString classe. Découvrez la fonction RewriteObjCStringLiteral dans lib/Rewrite/RewriteModernObjC.cpp dans le code source de Clang. Le compilateur émet simplement des données qui correspondent à la disposition des instances de la classe NSConstantString.

Il existe plusieurs possibilités pour les instances littérales NSArray et NSDictionary. Ils pourraient faire quelque chose comme ce qu'ils ont fait pour les chaînes littérales: coder en dur la présentation d'instance (pour une sous-classe spéciale) dans le compilateur et émettre des données dans cette présentation. Ils pourraient également demander au compilateur d'émettre un code qui crée simplement une instance au moment de l'exécution.

15
rob mayoff

De "Littéraux Objective-C"

1) NSNumber, NSDictionary et NSArray, les littéraux sont disponibles dans Xcode 4.4 .

2) NSDictionary et NSArray besoin de souscription " Xcode 4.4 et OS X 10.8 ou plus tard SDK "ou" Xcode 4.5 et iOS 6 ou version ultérieure du SDK "

Il me semble que l’abonnement a besoin d’un support d’exécution et ne fonctionnera donc pas avant iOS6 .

1
Andz