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的文字相同

我对此功能很感兴趣。它并不完全清楚,我只是如何文字NSString工作和一个如何使用它们NSArrayNSDictionaryNSNumber

有什么细节


不是一个答案,但有一些猜测这里:reddit.com/r/programming/comments/pso6x/xcode_43_released/...
阿尔扬Tijms

3
“此材料是否不受NDA的约束?” 你的问题是?
Hejazzman 2012年

7
不,苹果公司明确表示,这些添加内容不在邮件列表中。
griotspeak 2012年


3
以下是直接链接到Clang对Objective-C文字的讨论的链接:clang.llvm.org/docs/ObjectiveCLiterals.html
ThomasW,2012年

Answers:


393

http://cocoaheads.tumblr.com/post/17757846453/objective-c-literals-for-nsdictionary-nsarray-和复制的逐字记录:

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;

[编辑]

zxoqhttp://news.ycombinator.com/item?id=3672744增添了更多有趣的新的下标。(添加文字):

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

[编辑2]

在多个WWDC 2012会话中讨论了新的ObjC文字。我故意没有删除每张幻灯片的文件名和时间,因此您可以根据需要自己找到它们。它们本质上与本文中所述相同,但是我还将在图片上方提到一些新内容。

请注意,图像都很大。只需将它们拖到另一个标签中即可查看其原始大小

文字与拳击

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

迈克·阿什(Mike Ash)有很多关于这些新文字的文章。如果您想进一步了解这些东西,请确保将其签出



9
我可以看到这加快了我的编码速度!
Pedro Mancheno 2012年

12
有什么方法可以使xCode 4.3支持这些新符号?我希望他们- 现在 ......但我SO不是“上山”为他们...
亚历克斯·格雷

20
您在此处的图像中嵌入了许多文本内容,如果将这些文本内容发布为纯文本,则搜索引擎将更容易找到它们。
比尔蜥蜴2012年

5
@BilltheLizard我不同意。大部分的试验或者是未搜索的一些事情,如{[,或像一般的话arrayid@implementation。相关的关键字是literalobjcxcode不是[或的具体提及@implementation。您不希望这个问题出现在Google上的一般ObjC查询中,它只应在有人查询时显示objc literal,这在当前发生(由于标题和标签)。
Pooria Azimi

4
现在,这称为StackOverflow答案。干得好Pooria。
Nitish 2012年

15

Objective-C编译器对NSConstantString类(也称为__CFConstantString类)的实例的内存布局具有硬编码的知识。在clang源代码中签出RewriteObjCStringLiteral功能lib/Rewrite/RewriteModernObjC.cpp。编译器仅发出与NSConstantString类实例的布局匹配的数据。

文字NSArrayNSDictionary实例有两种可能。他们可以像处理文字字符串一样执行一些操作-在编译器中对实例布局(用于特殊的子类)进行硬编码,并在该布局中发出数据。或者,他们可以让编译器发出仅在运行时创建实例的代码。


2
和的对象文字语法的实现NSArrayNSDictionary完全不同NSString。编译器只是在运行时NSDictionaryNSArray在运行时生成调用。这也是为什么无法使用此语法初始化全局变量的原因(不同于NSString)。这将要求结果是一个编译时间常数。
Buzzy 2012年

1

摘自“ Objective-C文字”

1) NSNumberNSDictionaryNSArray文字中是可用的Xcode 4.4

2)NSDictionary并且NSArray下标需要“ Xcode 4.4OS X 10.8更高版本的SDK ”或“ Xcode 4.5iOS 6更高版本的SDK

在我看来,下标需要运行时支持,因此在iOS6之前无法使用


在同一篇文章中,“ iOS部署”列中显示“部署回iOS 4”
code007 2012年

1
我在Xcode 4.5编译的项目中不小心使用了数组文字。它可以在运行iOS5的iPad上正常运行。它无法在Xcode 4.2上编译,这是我发现自己这样做的方式。
JScarry

如果添加标题,则可以使下标与Xcode 4.4及其附带的iOS5 SDK配合使用:github.com/tewha/iOS-Subscripting/blob/master/…–
Steven Fisher
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.