始终可以使用vararg方法调用创建NSArray(以及NSDictionary/NSNumber),例如:
[NSArray arrayWithObjects: @"a", @"b", @"c", nil];
在LLVM和Clang的新改进中,可以使用内嵌文字来创建它们吗?
始终可以使用vararg方法调用创建NSArray(以及NSDictionary/NSNumber),例如:
[NSArray arrayWithObjects: @"a", @"b", @"c", nil];
在LLVM和Clang的新改进中,可以使用内嵌文字来创建它们吗?
LLVM代码库增加了this change,苹果在即将发布的Clang编译器版本中为文本添加了新的语法.
以前,数组是使用基于C的数组创建的,并在运行时转换为Objective-C对象,例如:
NSArray* array = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
注意,因为这是一个varargs元素,所以必须在列表的末尾提供一个结尾"nil".然而,现在有一个更简单的方法:
NSArray* array = @[ @"One", @"Two", @"Three" ];
请注意,[]之前的前导@是必需的,以区分它和普通C数组(或消息发送).还要注意,后面的"nil"不再是必需的.
在线字典文本也做了类似的更改,类似于JSON struct :
NSDictionary* dict = @{
@"Key1": @"Value1",
@"Key2": @"Value2",
};
最后,NSInteger(等)添加了一个新的文字:
NSNumber* value = @3.141;
请注意,尽管这适用于浮点(@3.141F
)和双精度(@3.141
),但它不适用于long double
,因为编译器不支持对它们进行包装.因此,@3.141D
将是编译时错误.
由于常量是如何定义的,@INT_MAX
是有效值,但@INT_MIN
不是,因为后者是通过编译时表达式定义的,而不是文本本身.
还有对布尔类型的扩展:
NSNumber* yes = @YES; // [NSNumber numberWithBool:YES]
NSNumber* no = @NO; // [NSNumber numberWithBool:NO]
NSNumber* trueBool = @true; // [NSNumber numberWithBool:(BOOL)true]
NSNumber* falseBool = @false; // [NSNumber numberWithBool:(BOOL)false]
此更改还引入了__objc_yes
和__objc_no
个文本,以支持仅通过文本值解析类型.它们的使用在预处理器中由#if __has_feature(objc_bool)
保护,但开发人员应该继续在代码中使用YES
和NO
.
最后,数组和字典现在都可以用数组括号下标,用作lvalue
和rvalue
表达式:
NSMutableArray* stuff = ...
id first = stuff[0];
stuff[0] = anotherObject;
NSMutableDictionary* moreStuff = ...
id conference = moreStuff[@"NSConf"]
moreStuff[@"SponsoredBy"] = @"NSConfDuck"
数组样式的下标(使用NSUInteger
)被映射到objectAtIndexedSubscript:
和相应的setObject:atIndexedSubscript:
,而字典访问则被objectForKeyedSubscript:
和setObject:forKeyedSubscript:
访问
文本的完整语法可以在Clang/LLVM website中看到
请注意,由于这个答案最初是编写的,所以Clang增加了对非文字的Objective-C表达式的支持,称为"装箱表达式"
这意味着可以使用@(3+4)
作为@7
的类似功能,使用@("Hello World")
作为@"Hello World"
.请注意,计算结果为null
的C表达式将导致异常,而@(null)
等参数将被视为编译时错误.
对于已知类型的类型,也可以使用"装箱枚举",因此
枚举{
可以放入一个带有@(North)
的装箱枚举类型中,该类型的值为0
.
盒装表达式将在clang 3.2之后提供.可以使用__has_feature(objc_boxed_expressions)
预处理器测试对其进行测试.