Jakie są szczegóły „Literałów Objective-C” wymienionych w informacjach o wersji Xcode 4.4?

188

Przeglądałem informacje o wersji Xcode 4.4 i zauważyłem to:

Kompilator LLVM 4.0

Xcode zawiera teraz kompilator Apple LLVM w wersji 4.0, w tym następujące nowe funkcje języka Objective-C: [...]
- Literały Objective C: tworzenie literałów dla NSArray, NSDictionary i NSNumber, tak samo jak literały dla NSString

Jestem zaintrygowany tą funkcją. To nie jest do końca jasne dla mnie, jak literały do NSStringpracy i jak można z nich korzystać NSArray, NSDictionaryi NSNumber.

Jakie są szczegóły?

Pedro Mancheno
źródło
Nie ma odpowiedzi, ale są tutaj spekulacje: reddit.com/r/programming/comments/pso6x/xcode_43_released/…
Arjan Tijms
3
„Czy ten materiał nie podlega NDA?” A twój problem to?
Hejazzman
7
Nie, Apple wyraźnie powiedział, że te dodatki nie znajdują się na liście mailingowej NDA.
griotspeak
2
LLVM ma na ten temat kilka dokumentów: clang.llvm.org/docs/LanguageExtensions.html#objc_lambdas
Steven Kramer
3
Oto link bezpośrednio do dyskusji Clanga na temat literałów Objective-C: clang.llvm.org/docs/ObjectiveCLiterals.html
ThomasW

Odpowiedzi:

393

Skopiowane dosłownie z http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and :

Literały celu C: można teraz tworzyć literały dla NSArray, NSDictionary i NSNumber (tak jak można tworzyć literały dla NSString)

NSArray Literals

Poprzednio:

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

Teraz:

array = @[ a, b, c ];

Literały NSDictionary

Poprzednio:

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

Teraz:

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

Literały NSNumber

Poprzednio:

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

Teraz:

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

[Edytować]

zxoq na http://news.ycombinator.com/item?id=3672744 dodał więcej interesujących nowych indeksów . (Dodano z literałami):

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

[Edytuj 2]

Nowe literały ObjC były omawiane podczas wielu sesji WWDC 2012 . Celowo nie usunąłem nazw plików i czasu każdego slajdu, więc możesz je znaleźć dla siebie, jeśli masz na to ochotę. Są to zasadniczo te same rzeczy, co stwierdzone w tym poście, ale jest też kilka nowych rzeczy, o których wspomnę powyżej obrazów.

Pamiętaj, że wszystkie obrazy są duże. Po prostu przeciągnij je do innej karty, aby wyświetlić je w oryginalnym rozmiarze

Literały i boks

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

Literały i boks

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

Indeksowanie kolekcji

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

Indeksowanie kolekcji

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

@ # liczby, @ {} słowniki, ciągi @ "", tablice @ [], wyrażenia @ ()


Ta część jest nowa. Dosłowne wyrażenia

Gdy masz wyrażenie ( M_PI / 16na przykład), umieść je w nawiasie.

Ta składnia działa dla wyrażeń liczbowych, wartości logicznych, znajdowania indeksu w ciągu (C-), wartości boolowskich, stałych wyliczania, a nawet ciągów znaków!

Dosłowne wyrażenia

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

Dosłowne wyrażenia

NSNumber *piOverSixteen = @( M_PI / 16 );

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

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

NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );

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

Więcej informacji na temat ciągów znaków i tego, jak / kiedy można użyć tej dosłownej składni:

Wyrażenia pudełkowe

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

Wyrażenia pudełkowe

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

Jak działają literały tablicowe

Jak działają literały tablicowe

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

Jak działają literały słownikowe

Jak działają literały słownikowe

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

Więcej o indeksowaniu tablic

Subskrybowanie tablicy

@implementation SongList {
    NSMutableArray *_songs;
}

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

Subskrybowanie tablicy

@implementation SongList {
    NSMutableArray *_songs;
}

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

Więcej o indeksowaniu słowników

Indeksowanie słowników

@implementation Database {
    NSMutableDictionary *_storage;
}

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

Indeksowanie słowników

@implementation Database {
    NSMutableDictionary *_storage;
}

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

[Edytuj 3]

Mike Ash świetnie napisał o tych nowych literałach. Jeśli chcesz dowiedzieć się więcej o tych rzeczach, koniecznie sprawdź to .


Pooria Azimi
źródło
9
Widzę, że to przyspiesza moje kodowanie!
Pedro Mancheno
12
Czy jest jakiś sposób, aby xCode 4.3 obsługiwał te nowe notacje? Chcę ich - TERAZ ... ale JESZCZE nie „wchodzę na górę” dla nich…
Alex Gray
20
Masz tu wiele treści tekstowych osadzonych w obrazach, które byłyby łatwiejsze do znalezienia przez wyszukiwarkę, gdyby zostały opublikowane jako zwykły tekst.
Bill the Lizard
5
@BilltheLizard Z całym szacunkiem się nie zgadzam. Większość testów jest albo un-przeszukiwać rzeczy podoba {i [czy są ogólne słowa takie jak array, idi @implementation. Odpowiednimi słowami kluczowymi są literal, objca xcodenie konkretne wzmianki o [lub @implementation. Nie chcesz, aby to pytanie wyświetlało się w przypadku ogólnych zapytań ObjC w Google, powinno być wyświetlane tylko wtedy, gdy ktoś zapyta objc literal, co dzieje się obecnie (dzięki tytułowi i tagom).
Pooria Azimi,
4
To się nazywa odpowiedź StackOverflow. Dobra robota Pooria.
Nitish,
15

Kompilator Objective-C ma ustaloną wiedzę na temat układu pamięci instancji NSConstantStringklasy, czyli __CFConstantStringklasy. Sprawdź RewriteObjCStringLiteralfunkcję w lib/Rewrite/RewriteModernObjC.cppkodzie źródłowym clang. Kompilator po prostu emituje dane, które pasują do układu instancji NSConstantStringklasy.

Istnieje kilka możliwości literału NSArrayi NSDictionaryinstancji. Mogą zrobić coś podobnego do literalnych ciągów - zakodować układ instancji (dla specjalnej podklasy) w kompilatorze i emitować dane w tym układzie. Mogą też poprosić kompilator o wyemitowanie kodu, który po prostu tworzy instancję w czasie wykonywania.

Rob Mayoff
źródło
2
Implementacja składni literału obiektu dla NSArrayi NSDictionaryjest zupełnie inna niż w przypadku NSString. Kompilator po prostu generuje wywołanie do NSDictionarylub NSArrayw czasie wykonywania. Z tego powodu zmiennych globalnych nie można zainicjować przy użyciu tej składni (w przeciwieństwie do NSString). Wymagałoby to, aby wynik był stałą czasową kompilacji.
Buzzy
1

Z „Literałów celu C”

1) NSNumber, NSDictionarya NSArrayliterały są dostępne w Xcode 4.4 .

2) NSDictionaryi NSArrayindeksowanie wymaga „ Xcode 4.4 i OS X 10.8 lub nowszy SDK ” lub „ Xcode 4.5 i iOS 6 lub nowszy SDK

Wydaje mi się, że indeksowanie wymaga obsługi środowiska wykonawczego i dlatego nie będzie działać przed iOS6 .

Andz
źródło
w tym samym artykule jest napisane „Wdrożenie z powrotem do iOS 4” w kolumnie „Wdrożenie iOS”
code007
1
Przypadkowo użyłem literałów tablicowych w projekcie skompilowanym z Xcode 4.5. Działa dobrze na iPadzie z systemem iOS5. Nie kompiluje się na Xcode 4.2, i tak się dowiedziałem, że to zrobiłem.
JScarry,
Subskrybowanie można włączyć do pracy z Xcode 4.4 i pakietem iOS5 SDK, który jest dostarczany, jeśli dodasz nagłówek: github.com/tewha/iOS-Subscripting/blob/master/…
Steven Fisher