Xcode 4.4リリースノートで言及されている「Objective-C Literals」の詳細は何ですか?


188

Xcode 4.4のリリースノートを調べていたところ、次のことに気づきました。

LLVM 4.0コンパイラ

Xcodeには、Apple LLVMコンパイラバージョン4.0が含まれ、次の新しい
Objective-C 言語機能が含まれています。[...] -Objective-Cリテラル:NSArray、NSDictionary、およびNSNumberのリテラルを作成します。

この機能に興味があります。それはちょうどどのようにリテラルの私には全く明らかではないNSString仕事とどのように1は、それらを使用することができNSArrayNSDictionaryNSNumber

詳細は?


ない答えが、いくつかの憶測がここにあります:reddit.com/r/programming/comments/pso6x/xcode_43_released/...
Arjan Tijms

3
「この資料はNDAの対象ではありませんか?」そしてあなたの問題は?
Hejazzman、2012

7
いいえ、アップルはこれらの追加はメーリングリストのNDAではないと明確に述べています。
griotspeak 2012年

2
LLVMにはこれに関するいくつかのドキュメントがあります:clang.llvm.org/docs/LanguageExtensions.html#objc_lambdas
Steven Kramer

3
Objective-CリテラルのClangディスカッションへの直接リンクは次のとおり
docs

回答:


393

http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-andから逐語的にコピー:

Objective-Cリテラル: NSArray、NSDictionary、およびNSNumberのリテラルを作成できるようになりました(NSStringのリテラルを作成できるように)。

NSArrayリテラル

以前は:

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

今:

array = @[ a, b, c ];

NSDictionaryリテラル

以前は:

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

今:

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

NSNumberリテラル

以前は:

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

今:

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

[編集]

http://news.ycombinator.com/item?id=3672744のzxoqに、より興味深い新しい添え字が追加されました。(リテラルで追加):

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

[編集2]

新しいObjCリテラルは、複数のWWDC 2012セッションで議論されました。各スライドのファイル名と時間は意図的に削除していないので、必要に応じて自分で見つけることができます。これらは基本的にこの投稿で述べたものと同じですが、画像の上で言及するいくつかの新しいものもあります。

画像はすべて大きいことに注意してください。それらを別のタブにドラッグするだけで、元のサイズで表示できます

リテラルとボクシング

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

@#数値、@ {}辞書、@ ""文字列、@ []配列、@()式


この部分は新しいです。式リテラル

M_PI / 16たとえば)式がある場合は、括弧内に置く必要があります。

この構文は、数値式、ブール値、(C-)文字列、ブール値、列挙型定数、さらには文字列でインデックスを検索するために機能します!

式リテラル

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

文字列と、このリテラル構文をいつどのように使用できるかについての詳細:

ボックス化文字列式

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...
}

配列リテラルのしくみ

配列リテラルのしくみ

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

辞書リテラルのしくみ

辞書リテラルのしくみ

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

配列の添え字の詳細

配列の添え字

@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;
}    

辞書の添え字の詳細

辞書の添え字

@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;
}

[編集3]

マイク・アッシュは、これらの新しいリテラルについて素晴らしい記事を書いています。このことについて詳しく知りたい場合は、ぜひチェックしてください



9
私はこれが私のコーディングをスピードアップしているのを見ることができます!
Pedro Mancheno、2012

12
これらの新しい表記法をサポートするxCode 4.3を入手する方法はありますか?-私はそれらをしたいNOW ...しかし、午前SO彼らのために...「山上がり」ではない
アレックス・グレイ

20
ここに画像に埋め込まれた多くのテキストコンテンツがあり、プレーンテキストとして投稿された場​​合、検索エンジンでより見つけやすくなります。
リザードの請求

5
@BilltheLizard私は敬意を払いません。テストのほとんどは、いずれかの非検索可能なものが好きである{[、などの一般的な言葉であるarrayid@implementation。関連するキーワードはliteralobjcおよびxcodeであり、[またはの具体的な言及ではありません@implementation。この質問をGoogleでの一般的なObjCクエリに表示したくない場合は、誰かがクエリを実行したときにのみ表示する必要がありますobjc literal(現在、タイトルとタグのおかげで)。
Pooria Azimi 2012

4
これはStackOverflow回答と呼ばれます。良い仕事Pooria。
ニティッシュ2012

15

Objective-Cコンパイラーは、NSConstantStringクラスとも呼ばれる、__CFConstantStringクラスのインスタンスのメモリーレイアウトのハードコーディングされた知識を持っています。clangソースコードのRewriteObjCStringLiteral関数を確認してくださいlib/Rewrite/RewriteModernObjC.cpp。コンパイラーは、NSConstantStringクラスのインスタンスのレイアウトに一致するデータを単に出力します。

リテラルNSArrayNSDictionaryインスタンスには2つの可能性があります。彼らは、リテラル文字列に対して行ったのと同じようなことを行うことができます-コンパイラーで(特別なサブクラスの)インスタンスレイアウトをハードコードし、そのレイアウトでデータを出力します。または、実行時にインスタンスを作成するだけのコードをコンパイラーに発行させることもできます。


2
およびのオブジェクトリテラル構文の実装は、の実装NSArrayNSDictionaryはかなり異なりNSStringます。コンパイラは単に、実行時NSDictionaryまたはNSArray実行時に呼び出しを生成するだけです。これは、(とは異なりNSString)この構文を使用してグローバル変数を初期化できない理由でもあります。この場合、結果はコンパイル時定数である必要があります。
バジー

1

「Objective-Cのリテラル」

1)NSNumberNSDictionaryおよびNSArrayリテラルはXcode 4.4で使用できます。

2)NSDictionaryNSArray添字の必要性" のXcode 4.4OS X 10.8またはそれ以降のSDK "または" Xcodeの4.5およびiOSの6またはそれ以降のSDK "

下付き文字にはランタイムサポートが必要なので、iOS6より前では機能しないようです


それはiOSの展開」欄の「バックのiOS 4への配備」と言う同じ記事で
code007

1
Xcode 4.5でコンパイルしたプロジェクトで誤って配列リテラルを使用しました。iOS5を実行しているiPadで正常に動作します。Xcode 4.2ではコンパイルできません。これは、私がそれを実行したことがわかった方法です。
JScarry

あなたは、ヘッダーを追加した場合のXcode 4.4とiOS5をSDKとその船で動作するように行うことができ添字:github.com/tewha/iOS-Subscripting/blob/master/...
スティーブン・フィッシャー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.