web-dev-qa-db-ja.com

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

私はXcode 4.4のリリースノートを見ていたが、これに気づいた:

LLVM 4.0コンパイラ

XcodeにはApple LLVM Compilerバージョン4.0が含まれるようになりました。これには、次のnewObjective-C言語機能が含まれます。[...]
-Objective-Cリテラル:NSStringのリテラルと同じように、NSArray、NSDictionary、NSNumberのリテラルを作成します

この機能に興味があります。 NSStringのリテラルがどのように機能し、NSArrayNSDictionary、およびNSNumberでどのようにそれらを使用できるかは、私には完全にはわかりません。

詳細は何ですか?

188
Pedro Mancheno

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;

[編集]

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

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

[編集2]

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

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

Literals & Boxing

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

Literals & Boxing

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

Collection Subscripting

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

Collection Subscripting

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

@# numbers, @{} dictionaries, @"" strings, @[] arrays, @() expressions


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

式(M_PI / 16など)がある場合は、括弧内に置く必要があります。

この構文は、数値式、ブール値、(C-)文字列内のインデックスの検索、ブール値、列挙定数、さらには文字列に対しても機能します!

Expression Literals

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

Expression Literals

NSNumber *piOverSixteen = @( M_PI / 16 );

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

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

NSNumber *writingDirection = @( NSWritingDirectionLeftToRight );

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

文字列と、このリテラル構文の使用方法/使用方法の詳細:

Boxed String Expressions

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

Boxed String Expressions

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

配列リテラルの仕組み

How array literals work

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

辞書リテラルの仕組み

How dictionary literals work

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

配列の添字付けの詳細

Array Subscripting

@implementation SongList {
    NSMutableArray *_songs;
}

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

Array Subscripting

@implementation SongList {
    NSMutableArray *_songs;
}

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

辞書の添え字付けの詳細

Dictionary Subscripting

@implementation Database {
    NSMutableDictionary *_storage;
}

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

Dictionary Subscripting

@implementation Database {
    NSMutableDictionary *_storage;
}

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

[編集3]

Mike Ash には、これらの新しいリテラルに関する優れた記事があります。このことについてもっと知りたい場合は、 check out を確認してください。


393
Pooria Azimi

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

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

15
rob mayoff

「Objective-C Literals」 から

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

2)NSDictionaryおよびNSArrayの添字には「Xcode 4.4およびOS X 10.8または後のSDK」または「Xcode 4.5およびiOS 6または後のSDK "

添え字にはランタイムサポートが必要であるため、以前は機能しませんでしたiOS6

1
Andz