Apa rincian "Sastra Objective-C" yang disebutkan dalam catatan rilis Xcode 4.4?

188

Saya membaca catatan rilis untuk Xcode 4.4 dan memperhatikan ini:

LLVM 4.0 Compiler

Xcode sekarang termasuk Apple LLVM Compiler versi 4.0, termasuk fitur-fitur baru bahasaObjective-C berikut: [...]
- Sasaran-C literal: membuat literal untuk NSArray, NSDictionary, dan NSNumber, sama seperti literal untuk NSString

Saya tertarik dengan fitur ini. Ini tidak sepenuhnya jelas bagi saya betapa literal untuk NSStringbekerja dan bagaimana seseorang bisa menggunakannya pada NSArray, NSDictionary, danNSNumber .

Apa detailnya?

Pedro Mancheno
sumber
Bukan jawaban, tetapi ada beberapa spekulasi di sini: reddit.com/r/programming/comments/pso6x/xcode_43_released/…
Arjan Tijms
3
"Bukankah materi ini tunduk pada NDA?" Dan masalahnya adalah?
Hejazzman
7
Tidak, Apple telah secara eksplisit mengatakan bahwa penambahan ini bukan NDA di milis.
griotspeak
2
LLVM memiliki beberapa dokumen tentang ini: clang.llvm.org/docs/LanguageExtensions.html#objc_lambdas
Steven Kramer
3
Berikut ini tautan langsung ke diskusi Clang tentang Objective-C literals: clang.llvm.org/docs/ObjectiveCLiterals.html
ThomasW

Jawaban:

393

Salinan kata demi kata dari http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-and :

Objective-C literals: seseorang sekarang dapat membuat literal untuk NSArray, NSDictionary, dan NSNumber (seperti halnya seseorang dapat membuat literal untuk NSString)

NSArray Literals

Sebelumnya:

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

Sekarang:

array = @[ a, b, c ];

NSDictionary Literals

Sebelumnya:

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

Sekarang:

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

NSNumber Literals

Sebelumnya:

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

Sekarang:

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

[Sunting]

zxoq di http://news.ycombinator.com/item?id=3672744 telah menambahkan langganan baru yang lebih menarik. (Ditambahkan dengan literal):

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

[Sunting 2]

Literal ObjC baru dibahas dalam beberapa sesi WWDC 2012 . Saya sengaja tidak menghapus nama file dan waktu setiap slide sehingga Anda dapat menemukannya sendiri jika Anda mau. Mereka pada dasarnya hal yang sama seperti yang dinyatakan dalam posting ini, tetapi ada juga beberapa hal baru yang akan saya sebutkan di atas gambar.

Harap perhatikan bahwa gambar semuanya besar. Cukup seret ke tab lain untuk melihatnya dalam ukuran aslinya

Literal & Tinju

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

Literal & Tinju

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

Berlangganan Koleksi

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

Berlangganan Koleksi

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

@ # number, @ {} kamus, string @ "" array, @ [] array, ekspresi @ ()


Bagian ini baru. Literal Ekspresi

Ketika Anda memiliki ekspresi ( M_PI / 16misalnya), Anda harus meletakkannya di dalam tanda kurung.

Sintaks ini berfungsi untuk ekspresi angka, boolean, menemukan indeks dalam string (C-), nilai boolean, konstanta enum, dan bahkan string karakter!

Literal Ekspresi

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

Literal Ekspresi

NSNumber *piOverSixteen = @( M_PI / 16 );

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

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

NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );

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

Lebih lanjut tentang string karakter dan bagaimana / kapan Anda dapat menggunakan sintaks literal ini:

Ekspresi String Kotak

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

Ekspresi String Kotak

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

Cara kerja literal array

Cara kerja literal array

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

Cara kerja kamus literal

Cara kerja kamus literal

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

Lebih lanjut tentang array subscript

Array Berlangganan

@implementation SongList {
    NSMutableArray *_songs;
}

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

Array Berlangganan

@implementation SongList {
    NSMutableArray *_songs;
}

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

Lebih lanjut tentang subskripsi kamus

Berlangganan Kamus

@implementation Database {
    NSMutableDictionary *_storage;
}

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

Berlangganan Kamus

@implementation Database {
    NSMutableDictionary *_storage;
}

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

[Sunting 3]

Mike Ash memiliki artikel bagus tentang literal baru ini. Jika Anda ingin tahu lebih banyak tentang hal ini, pastikan untuk memeriksanya .


Pooria Azimi
sumber
9
Saya bisa melihat ini mempercepat pengkodean saya!
Pedro Mancheno
12
Apakah ada cara untuk mendapatkan xCode 4.3 untuk mendukung notasi baru ini? Saya ingin mereka - SEKARANG ... tapi SANGAT tidak "naik gunung" untuk mereka ...
Alex Gray
20
Anda memiliki banyak konten teks yang tertanam dalam gambar di sini yang akan lebih mudah ditemukan oleh mesin pencari jika itu diposting sebagai teks biasa.
Bill the Lizard
5
@BilltheLizard Saya dengan hormat tidak setuju. Sebagian besar tes adalah hal-hal yang tidak dapat dicari seperti {dan [, atau kata-kata umum seperti array, iddan @implementation. Kata kunci yang relevan adalah literal, objcdan xcode, bukan spesifik menyebutkan [atau @implementation. Anda tidak ingin pertanyaan ini muncul untuk permintaan ObjC umum di Google, itu hanya akan ditampilkan ketika seseorang bertanya objc literal, yang terjadi saat ini (berkat judul dan tag).
Pooria Azimi
4
Sekarang disebut jawaban StackOverflow. Kerja bagus, Pooria.
Nitish
15

Compiler Objective-C memiliki pengetahuan hardcoded tentang tata letak memori instance NSConstantStringkelas, alias __CFConstantStringkelas. Periksa RewriteObjCStringLiteralfungsi di lib/Rewrite/RewriteModernObjC.cppdalam kode sumber dentang. Kompilator hanya memancarkan data yang cocok dengan tata letak contohNSConstantString kelas.

Ada beberapa kemungkinan untuk literal NSArraydan NSDictionarycontoh. Mereka dapat melakukan sesuatu seperti apa yang mereka lakukan untuk string literal - hardcode tata letak instance (untuk subkelas khusus) di kompiler dan memancarkan data dalam tata letak itu. Atau mereka dapat memiliki kode emisi kompiler yang hanya membuat instance saat runtime.

rob mayoff
sumber
2
Implementasi sintaksis objek literal untuk NSArraydan NSDictionarysangat berbeda dari NSString. Kompiler hanya menghasilkan panggilan ke NSDictionaryatau NSArraysaat runtime. Ini juga mengapa variabel global tidak dapat diinisialisasi menggunakan sintaks ini (tidak seperti NSString). Ini akan membutuhkan hasilnya menjadi konstanta waktu kompilasi.
Buzzy
1

Dari "Objective-C Literals"

1) NSNumber, NSDictionarydan NSArrayliteral tersedia dalam Xcode 4.4 .

2) NSDictionarydan NSArraysubskrip memerlukan " Xcode 4.4 dan OS X 10.8 atau lebih baru SDK " atau " Xcode 4.5 dan iOS 6 atau lebih baru SDK "

Menurut saya, subskrip ini membutuhkan dukungan runtime dan karenanya tidak akan berfungsi sebelum iOS6 .

Andz
sumber
dalam artikel yang sama dikatakan "Menyebarkan kembali ke iOS 4" di kolom 'penyebaran iOS'
code007
1
Saya tidak sengaja menggunakan literal array dalam proyek yang saya kompilasi dengan Xcode 4.5. Ini berjalan dengan baik di iPad yang menjalankan iOS5. Itu tidak dikompilasi pada Xcode 4.2, yang merupakan bagaimana saya mengetahui bahwa saya melakukannya.
JScarry
Berlangganan dapat dibuat untuk bekerja dengan Xcode 4.4 dan iOS5 SDK yang dikirimkan jika Anda menambahkan header: github.com/tewha/iOS-Subscripting/blob/master/…
Steven Fisher