Xcode 4.4发行说明中提到的“ Objective-C Literals”的细节是什么?

我在浏览 Xcode 4.4的发布说明时注意到:

LLVM 4.0编译器

Xcode 现在包括 Apple LLVM Compiler 4.0版,包括以下新的 Objective-C 语言特性: [...]
Objective-C 文本: 为 NSArray、 NSDictionary 和 NSNumber 创建文本,就像为 NSString 创建文本一样

我对这个功能很感兴趣。我不完全清楚 NSString的文字是如何工作的,以及如何在 NSArrayNSDictionaryNSNumber上使用它们。

细节是什么?

62106 次浏览

Objective-C 编译器对 NSConstantString类(也就是 __CFConstantString类)实例的内存布局有硬编码的知识。在 clang 源代码中查看 lib/Rewrite/RewriteModernObjC.cpp中的 RewriteObjCStringLiteral函数。编译器只发出与 NSConstantString类的实例布局匹配的数据。

对于字面 NSArrayNSDictionary实例有几种可能性。它们可以像处理文字字符串那样——在编译器中硬编码实例布局(针对特殊的子类) ,并在该布局中发出数据。或者,它们可以让编译器发出代码,这些代码只是在运行时创建一个实例。

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 Literals

前情提要:

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;

[编辑]

Zxoq at http://news.ycombinator.com/item?id=3672744添加了更有趣的新订阅。(添加了文字) :

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

[编辑2]

在多个 WWDC 2012会议中讨论了新的 Object 文本。我故意没有删除的文件名和每个幻灯片的时间,所以你可以为自己找到他们,如果你喜欢。它们本质上和本文所述是一样的,但也有一些新的东西,我会在上面的图片中提到。

请注意,图像都是大的。只需将它们拖动到另一个标签页,以查看它们的原始大小

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 写了一篇关于这些新文字的文章。如果你想知道更多关于这方面的东西,确保 看看这个


来自 “ Objective-C Literals”

1) NSNumberNSDictionaryNSArray文字在 Xcode 4.4中可用。

2) NSDictionaryNSArray订阅需要「 Xcode 4.4OS X 10.8稍后 SDK」或「 Xcode 4.5IOS6稍后 SDK

在我看来,订阅需要运行时支持,因此在 IOS6之前无法工作。

Apple LLVM Compiler 4.0增加了对 Objective-C 的文字支持,它从 at sign @开始

NSNumber 文字

NSNumber *someBool = [NSNumber numberWithBool:YES];
//BOOL literal
NSNumber *someBool = @YES;
     

NSNumber *someChar= [NSNumber numberWithChar:'a'];
//character literal
NSNumber *someChar = @'a';
     

NSNumber *someInt = [NSNumber numberWithInt:1];
NSNumber *someInt = [NSNumber numberWithUnsignedInt:1U];
NSNumber *someInt = [NSNumber numberWithLong:1L];
NSNumber *someInt = [NSNumber numberWithLongLong:1LL];
//integer literal
NSNumber *someInt = @1;
NSNumber *someInt = @1U;
NSNumber *someInt = @1L;
NSNumber *someInt = @1LL;
     

NSNumber *someFloat = [NSNumber numberWithFloat:3.141592654F];
NSNumber *someFloat = [NSNumber numberWithDouble:3.1415926535];
//float literal
NSNumber *someFloat = @3.141592654F;
NSNumber *someFloat = @3.1415926535;

集合文字

NSArray *someArray = [NSArray arrayWithObjects: @"A", @"B", @"C", nil];
//array literal
NSArray *someArray = @[ @"A", @"B", @"C" ];


NSDictionary *someDict = [NSDictionary dictionaryWithObjectsAndKeys:
@"key1", @"value1",
@"key1", @"value2",
nil];
//dictionary literal
NSDictionary *someDict = @{ @"Character" : @"Zelda",
@"key1" : @"value2",
@"key2" : @value2 };

集合订阅

NSString *var1 = [someArray objectAtIndex:0]; // Returns 'A'
NSString *var2 = [someDict objectForKey:@"key1"]; // Returns 'value1'
//Collection Subscripting
//read
NSString *var1 = someArray[0]; // Returns 'A'
NSString *var2 = someDict[@"key1"]; // Returns 'value1'
//write to mutable collection
someArray[0] = @"AA";
someDict[@"key1"] = @"value11";

方框表达式 -C 风格的表达式转换为 Objective-C。可以处理数字、枚举和结构

//Syntax @( <expression> )
[NSNumber numberWithInt:(INT_MAX + 1)];
//Boxed Expressions
NSNumber *var = @(INT_MAX + 1);