Quels sont les détails des «littéraux Objective-C» mentionnés dans les notes de mise à jour de Xcode 4.4?

188

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

Compilateur LLVM 4.0

Xcode inclut désormais le compilateur Apple LLVM version 4.0, y compris les nouvelles fonctionnalités du langage Objective-C suivantes: [...]
- Littéraux Objective-C: créez des littéraux pour NSArray, NSDictionary et NSNumber, tout comme les littéraux pour NSString

Je suis intrigué par cette fonctionnalité. Il est pas tout à fait clair pour moi à quel point littéraux pour le NSStringtravail et la façon dont on pourrait les utiliser sur NSArray, NSDictionaryet NSNumber.

Quels sont les détails?

Pedro Mancheno
la source
Pas de réponse, mais il y a des spéculations ici: reddit.com/r/programming/comments/pso6x/xcode_43_released/…
Arjan Tijms
3
"Ce matériel n'est-il pas soumis à une NDA?" Et votre problème est?
Hejazzman
7
Non, Apple a explicitement déclaré que ces ajouts ne sont pas NDA sur la liste de diffusion.
griotspeak
2
LLVM a quelques documents à ce sujet: clang.llvm.org/docs/LanguageExtensions.html#objc_lambdas
Steven Kramer
3
Voici un lien directement vers la discussion de Clang sur les littéraux Objective-C: clang.llvm.org/docs/ObjectiveCLiterals.html
ThomasW

Réponses:

393

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

Objective-C littéraux: on peut maintenant créer des littéraux pour NSArray, NSDictionary et NSNumber (tout 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 };

Littéraux NSNumber

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;

[Éditer]

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

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

[Modifier 2]

Les nouveaux littéraux ObjC ont été discutés lors de plusieurs sessions WWDC 2012 . Je n'ai pas supprimé intentionnellement les noms de fichiers et l'heure de chaque diapositive afin que vous puissiez les trouver par vous-même si vous le souhaitez. Ils sont essentiellement la même chose que celle indiquée dans cet article, mais il y a aussi quelques nouvelles choses que je mentionnerai au-dessus des images.

Veuillez noter que les images sont toutes grandes. Faites-les simplement glisser dans un autre onglet pour les afficher dans leur taille d'origine

Littéraux et boxe

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

Littéraux et boxe

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

Indice de collection

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

Indice de collection

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

@ # nombres, @ {} dictionnaires, @ "" chaînes, @ [] tableaux, @ () expressions


Cette partie est nouvelle. Littéraux d'expression

Lorsque vous avez une expression ( M_PI / 16par exemple), vous devez la 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 d'énumération et même les chaînes de caractères!

Littéraux d'expression

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")];

Littéraux d'expression

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 vous pouvez utiliser cette syntaxe littérale:

Expressions de chaîne encadrées

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

Expressions de chaîne encadrées

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

Fonctionnement des littéraux de tableau

Fonctionnement des littéraux de tableau

// 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

Comment fonctionnent les littéraux de dictionnaire

// 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];

En savoir plus sur l'indice de tableau

Indice de tableau

@implementation SongList {
    NSMutableArray *_songs;
}

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

Indice de tableau

@implementation SongList {
    NSMutableArray *_songs;
}

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

En savoir plus sur l'indexation du dictionnaire

Indexation du dictionnaire

@implementation Database {
    NSMutableDictionary *_storage;
}

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

Indexation du dictionnaire

@implementation Database {
    NSMutableDictionary *_storage;
}

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

[Modifier 3]

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


Pooria Azimi
la source
9
Je peux voir cela accélérer mon codage!
Pedro Mancheno
12
Existe-t-il un moyen d'obtenir xCode 4.3 pour prendre en charge ces nouvelles notations? Je veux qu'ils - MAINTENANT ... mais je suis SO pas « montais la montagne » pour eux ...
Alex Gray
20
Vous avez ici beaucoup de contenu textuel intégré dans des images qui serait plus accessible par un moteur de recherche s'il était publié sous forme de texte brut.
Bill the Lizard
5
@BilltheLizard Je suis respectueusement en désaccord. La plupart des tests sont soit des choses non interrogeables comme {et [, soit des mots génériques comme array, idet @implementation. Les mots clés pertinents sont literal, objcet xcode, pas les mentions spécifiques de [ou @implementation. Vous ne voulez pas que cette question apparaisse pour les requêtes ObjC générales sur Google, elle ne devrait être affichée que lorsque quelqu'un interroge objc literal, ce qui se produit actuellement (grâce au titre et aux balises).
Pooria Azimi
4
Cela s'appelle maintenant une réponse StackOverflow. Bon travail Pooria.
Nitish
15

Le compilateur Objective-C a une connaissance codée en dur de la disposition de la mémoire des instances de la NSConstantStringclasse, alias la __CFConstantStringclasse. Découvrez la RewriteObjCStringLiteralfonction lib/Rewrite/RewriteModernObjC.cppdans le code source de clang. Le compilateur émet simplement des données qui correspondent à la disposition des instances de la NSConstantStringclasse.

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

Rob Mayoff
la source
2
L'implémentation de la syntaxe littérale d'objet pour NSArrayet NSDictionaryest assez différente de celle de NSString. Le compilateur génère simplement un appel vers NSDictionaryou NSArrayau moment de l'exécution. C'est aussi pourquoi les variables globales ne peuvent pas être initialisées à l'aide de cette syntaxe (contrairement à NSString). Cela nécessiterait que le résultat soit une constante de temps de compilation.
Buzzy le
1

À partir de "Littéraux Objective-C"

1) NSNumber, NSDictionaryet les NSArraylittéraux sont disponibles dans Xcode 4.4 .

2) NSDictionaryet les NSArrayindices nécessitent " Xcode 4.4 et OS X 10.8 ou version ultérieure SDK " ou " Xcode 4.5 et iOS 6 ou version ultérieure SDK "

Il me semble que l'indication nécessite un support d'exécution et ne fonctionnera donc pas avant iOS6 .

Andz
la source
dans le même article, il est dit "
Se déploie
1
J'ai accidentellement utilisé des littéraux de tableau dans un projet que j'ai compilé avec Xcode 4.5. Il fonctionne bien sur un iPad exécutant iOS5. Il ne se compile pas sur Xcode 4.2, c'est ainsi que j'ai découvert que je l'avais fait.
JScarry
L'abonnement peut être fait pour fonctionner avec Xcode 4.4 et le SDK iOS5 avec lequel il est livré si vous ajoutez un en-tête: github.com/tewha/iOS-Subscripting/blob/master/…
Steven Fisher