objective c - ¿Cuáles son los detalles de "Objective-C Literals" mencionados en las notas de la versión de Xcode 4.4?
objective-c-literals (3)
Revisé las notas de la versión de Xcode 4.4 y noté esto:
Compilador LLVM 4.0
Xcode ahora incluye el Apple LLVM Compiler versión 4.0, que incluye las siguientes características del nuevo lenguaje Objective-C: [...]
- Literales Objective-C: crea literales para NSArray, NSDictionary y NSNumber, al igual que los literales para NSString
Estoy intrigado acerca de esta característica. No me queda del todo claro cómo funcionan los literales de NSString
y cómo se podrían usar en NSArray
, NSDictionary
y NSNumber
.
¿Cuáles son los detalles?
Copiado textualmente de http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and :
Literales Objective-C: ahora se pueden crear literales para NSArray, NSDictionary y NSNumber (como uno puede crear literales para NSString)
NSArray Literals
Previamente:
array = [NSArray arrayWithObjects:a, b, c, nil];
Ahora:
array = @[ a, b, c ];
NSDictionary Literals
Previamente:
dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3]
forKeys:@[k1, k2, k3]];
Ahora:
dict = @{ k1 : o1, k2 : o2, k3 : o3 };
NSNumber Literales
Previamente:
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];
Ahora:
NSNumber *number;
number = @''X'';
number = @12345;
number = @12345ul;
number = @12345ll;
number = @123.45f;
number = @123.45;
number = @YES;
[Editar]
zxoq en http://news.ycombinator.com/item?id=3672744 ha agregado nuevas suscripciones más interesantes. (Agregado con literales):
arr[1] === [arr objectAtIndex:1]
dict[@"key"] === [dict objectForKey:@"key"]
[Editar 2]
Los nuevos literales ObjC se discutieron en múltiples sesiones WWDC 2012 . Intencionalmente no eliminé los nombres de los archivos y la hora de cada diapositiva para que puedas encontrarlos por ti mismo si te apetece. Son esencialmente lo mismo que se indica en esta publicación, pero también hay algunas cosas nuevas que mencionaré arriba de las imágenes.
Tenga en cuenta que las imágenes son todas grandes. Simplemente arrástralos a otra pestaña para verlos en su tamaño original
[NSNumber numberWithint:42]
[NSNumber numberWithDouble:10.8]
[NSNumber numberWithBool:YES]
[NSNumber numberWithint:6 + x * 2012]
@42
@10.8
@YES
@(6 + x * 2012)
[NSArray arrayWithObjects: a, b, c, nil]
[array objectAtIndex:i]
[NSDictionary dictionaryWithObjectsAndKeys: v1, k1, v2, k2, nil];
[dictionary valueForKey:k]
@[a, b, c]
array[i]
@{k1:v1, k2:v2}
dictionary[k]
Esta parte es nueva. Literales de expresión
Cuando tienes una expresión ( M_PI / 16
por ejemplo) debes ponerla entre paréntesis.
Esta sintaxis funciona para expresiones numéricas, booleanos, encontrar un índice en una cadena (C-), valores booleanos, constantes enum e incluso cadenas de caracteres.
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")];
NSNumber *piOverSixteen = @( M_PI / 16 );
NSNumber *hexDigit = @( "0123456789ABCDEF"[i % 16] );
NSNumber *usesScreenFonts = @( [NSLayoutManager usesScreenFonts] );
NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );
NSNumber *path = @( getenv("PATH") );
Más acerca de las cadenas de caracteres y cómo / cuándo puede usar esta sintaxis literal:
NSString *path = [NSString stringWithUTF8String: getenv("PATH")];
for (NSString *dir in [path componentsSeparatedByString: @":"]) {
// search for a file in dir...
}
NSString *path = @( getenv("PATH") );
for (NSString *dir in [path componentsSeparatedByString: @":"]) {
// search for a file in dir...
}
Cómo funcionan los literales de matriz
// 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];
Cómo funcionan los literales de diccionario
// 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];
Más sobre la suscripción de matrices
@implementation SongList {
NSMutableArray *_songs;
}
- (Song *)replaceSong:(Song *)newSong atindex:(NSUinteger)idx {
Song *oldSong = [_songs objectAtIndex:idx];
[_songs replaceObjectAtindex:idx withObject:newSong];
return oldSong;
}
@implementation SongList {
NSMutableArray *_songs;
}
- (Song *)replaceSong:(Song *)newSong atindex:(NSUinteger)idx {
Song *oldSong = _songs[idx];
_songs[idx] = newSong;
return oldSong;
}
Más sobre la subscripción de diccionarios
@implementation Database {
NSMutableDictionary *_storage;
}
- (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key {
id oldObject = [_storage objectForKey:key];
[_storage setObject:object forKey:key];
return oldObject;
}
@implementation Database {
NSMutableDictionary *_storage;
}
- (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key {
id oldObject = _storage[key];
_storage[key] = newObject;
return oldObject;
}
[Editar 3]
Mike Ash tiene una gran reseña sobre estos nuevos literales. Si quieres saber más sobre esto, asegúrate de verificarlo .
1) Los NSNumber
, NSDictionary
y NSArray
están disponibles en Xcode 4.4 .
2) Los subscriptores NSDictionary
y NSArray
necesitan " Xcode 4.4 y OS X 10.8 o posterior SDK " o " Xcode 4.5 y iOS 6 o posterior SDK "
Me parece que el subscriptor necesita soporte de tiempo de ejecución y, por lo tanto, no funcionará antes de iOS6 .
El compilador Objective-C tiene un conocimiento codificado del diseño de la memoria de las instancias de la clase NSConstantString
, también conocida como la clase __CFConstantString
. Consulte la función RewriteObjCStringLiteral
en lib/Rewrite/RewriteModernObjC.cpp
en el código fuente de clang. El compilador simplemente emite datos que coinciden con el diseño de las instancias de la clase NSConstantString
.
Hay un par de posibilidades para las instancias NSArray
y NSDictionary
literales. Podrían hacer algo como lo que hicieron para cadenas literales: codificar el diseño de la instancia (para una subclase especial) en el compilador y emitir datos en ese diseño. O podrían hacer que el compilador emita código que simplemente crea una instancia en tiempo de ejecución.