Quais são os detalhes de "Literais Objective-C" mencionados nas notas de versão do Xcode 4.4?


188

Eu estava examinando as notas de versão do Xcode 4.4 e percebi o seguinte:

Compilador LLVM 4.0

O Xcode agora inclui o Apple LLVM Compiler versão 4.0, incluindo os seguintes recursos da linguagem newObjective-C: [...]
- literais de Objective-C: criam literais para NSArray, NSDictionary e NSNumber, exatamente como os literais para NSString.

Estou intrigado com esse recurso. Não é totalmente claro para mim o quão literais para NSStringo trabalho e como se poderia usá-los em NSArray, NSDictionarye NSNumber.

Quais são os detalhes?


Não é uma resposta, mas há alguma especulação aqui: reddit.com/r/programming/comments/pso6x/xcode_43_released/...
— Arjan Tijms

3
"Este material não está sujeito a um NDA?" E o seu problema é?
— 21412 Hejazzman

7
Não, a Apple disse explicitamente que essas adições não são NDA na lista de distribuição.
— griotspeak

2
LLVM tem alguns documentos sobre este assunto: clang.llvm.org/docs/LanguageExtensions.html#objc_lambdas
— Steven Kramer

3
Aqui está um link diretamente para a discussão Clang de literais Objective-C: clang.llvm.org/docs/ObjectiveCLiterals.html
— Thomasw

Respostas:


393

Copiado literalmente de http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and :

Literais Objective-C: agora é possível criar literais para NSArray, NSDictionary e NSNumber (assim como se pode criar literais para NSString)

NSArray Literals

Anteriormente:

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

Agora:

array = @[ a, b, c ];

Literais do NSDictionary

Anteriormente:

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

Agora:

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

Literais NSNumber

Anteriormente:

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

Agora:

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

[Editar]

O zxoq em http://news.ycombinator.com/item?id=3672744 adicionou uma nova inscrição mais interessante. (Adicionado com literais):

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

[Editar 2]

Os novos literais da ObjC foram discutidos em várias sessões da WWDC 2012 . Intencionalmente, não removi os nomes dos arquivos e a hora de cada slide, para que você possa encontrá-los por conta própria, se quiser. Eles são essencialmente a mesma coisa que afirmamos neste post, mas também há algumas coisas novas que mencionarei acima das imagens.

Observe que as imagens são todas grandes. Basta arrastá-los para outra guia para visualizá-los no tamanho original

Literais e Boxe

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

Literais e Boxe

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

Subscrição de Coleção

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

Subscrição de Coleção

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

@ # números, @ {} dicionários, @ "" strings, @ [] matrizes, @ () expressões


Esta parte é nova. Literais de Expressão

Quando você tem uma expressão ( M_PI / 16por exemplo), deve colocá-la entre parênteses.

Essa sintaxe funciona para expressões numéricas, booleanos, localizando um índice em uma string (C-), valores booleanos, constantes enum e até strings de caracteres!

Literais de Expressão

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

Literais de Expressão

NSNumber *piOverSixteen = @( M_PI / 16 );

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

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

NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );

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

Mais sobre cadeias de caracteres e como / quando você pode usar esta sintaxe literal:

Expressões de string em caixa

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

Expressões de string em caixa

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

Como literais de matriz funcionam

Como literais de matriz funcionam

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

Como os literais do dicionário funcionam

Como os literais do dicionário funcionam

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

Mais sobre assinatura de array

Subscrição de Matrizes

@implementation SongList {
    NSMutableArray *_songs;
}

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

Subscrição de Matrizes

@implementation SongList {
    NSMutableArray *_songs;
}

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

Mais sobre subscrição de dicionário

Subscrição de Dicionário

@implementation Database {
    NSMutableDictionary *_storage;
}

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

Subscrição de Dicionário

@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 tem um ótimo artigo sobre esses novos literais. Se você quiser saber mais sobre esse material, verifique .



9
Eu posso ver isso acelerando minha codificação!
— Pedro Mancheno

12
Existe alguma maneira de obter o xCode 4.3 para suportar essas novas notações? Eu quero que eles - EMPRESA ... mas estou SO não "subir a montanha" para eles ...
— Alex Gray

20
Você tem muito conteúdo textual incorporado nas imagens aqui que seriam mais acessíveis por um mecanismo de pesquisa se ele fosse publicado como texto sem formatação.
— Bill the Lizard

5
@ BilltheLizard Eu discordo respeitosamente. A maior parte do teste é o UN-pesquisável coisas como {e [, ou são palavras genéricas como array, ide @implementation. As palavras-chave relevantes são literal, objce xcodenão as menções específicas de [ou @implementation. Você não deseja que essa pergunta apareça para consultas gerais sobre ObjC no Google, ela deve ser exibida apenas quando alguém fizer uma consulta objc literal, o que acontece no momento (graças ao título e às tags).
— Pooria Azimi

4
Agora isso é chamado de resposta StackOverflow. Bom trabalho, Pooria.
— Nitish

15

O compilador Objective-C codificou o conhecimento do layout de memória das instâncias da NSConstantStringclasse, também conhecida como __CFConstantStringclasse. Confira a RewriteObjCStringLiteralfunção no lib/Rewrite/RewriteModernObjC.cppcódigo-fonte do clang. O compilador simplesmente emite dados que correspondem ao layout das instâncias doNSConstantString classe.

Existem algumas possibilidades para literais NSArraye NSDictionaryinstâncias. Eles poderiam fazer algo parecido com o que fizeram para seqüências de caracteres literais - codificar o layout da instância (para uma subclasse especial) no compilador e emitir dados nesse layout. Ou eles podem fazer o compilador emitir um código que simplesmente cria uma instância em tempo de execução.


2
A implementação da sintaxe literal do objeto para NSArraye NSDictionaryé bem diferente da de NSString. O compilador simplesmente gera uma chamada para NSDictionaryou NSArrayem tempo de execução. É também por isso que variáveis ​​globais não podem ser inicializadas usando esta sintaxe (diferente NSString). Isso exigiria que o resultado fosse uma constante de tempo de compilação.
— Buzzy

1

Dos literais de Objective-C

1) NSNumber, NSDictionarye NSArrayliterais estão disponíveis em Xcode 4,4 .

2) NSDictionarye a NSArrayassinatura precisa do " Xcode 4.4 e OS X 10.8 ou posterior SDK " ou " Xcode 4.5 e iOS 6 ou posterior SDK "

Parece-me que a assinatura precisa de suporte de tempo de execução e, portanto, não funcionará antes do iOS6 .


no mesmo artigo, ele diz "Implanta de volta no iOS 4" na coluna 'Implantação do iOS'
— code007

1
Eu acidentalmente usei literais de matriz em um projeto que compilei com o Xcode 4.5. Ele roda bem em um iPad com iOS5. Ele não é compilado no Xcode 4.2, e foi assim que descobri que o fiz.
— JScarry

Subscripting pode ser feito para trabalhar com o Xcode 4.4 eo SDK iOS5 ele vem com se você adicionar um cabeçalho: github.com/tewha/iOS-Subscripting/blob/master/...
— Steven Fisher
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.