Objective c 为什么NSNumber文本不能在静态声明中使用

Objective c 为什么NSNumber文本不能在静态声明中使用,objective-c,ios,static,ios6,nsnumber,Objective C,Ios,Static,Ios6,Nsnumber,我宣布: static NSString *a = @"a"; 这是iOS6中的一个正确声明(使用编译器版本应该更正确,但我目前还不知道)。我认为对于数字文字来说: static NSNumber *b=@1; 可能是有效的声明。编译器告诉我,初始值设定项元素不是编译时常量。这让我有点吃惊。由于NSNumber与NSString一样是不可变的,而且我使用的是字符串大小写形式的文本,所以我认为它也可能是有效的 有人对此差异有合理的解释吗?第一行是编译时常量,因为您正在分配@“a”,而不是类似于

我宣布:

static NSString *a = @"a";
这是iOS6中的一个正确声明(使用编译器版本应该更正确,但我目前还不知道)。我认为对于数字文字来说:

static NSNumber *b=@1;
可能是有效的声明。编译器告诉我,
初始值设定项元素不是编译时常量。这让我有点吃惊。由于
NSNumber
NSString
一样是不可变的,而且我使用的是字符串大小写形式的文本,所以我认为它也可能是有效的


有人对此差异有合理的解释吗?

第一行是编译时常量,因为您正在分配
@“a”
,而不是类似于
静态NSString*a=[NSString stringWithFormat:@“a”](将引发相同的错误)

但是对于
NSNumber
静态NSNumber*b=@1
实际上相当于
静态NSNumber*b=[NSNumber numberwhithint:1]。欲知详情

请注意,在上述情况下,右侧不是编译时常量。它是一个必须在运行时计算的表达式。在C和Objective-C中,静态变量必须用编译时常量初始化

如果您想将
NSNumber
作为
const
使用,可以使用此处提到的方法进行检查

而且

需要注意的是,没有一个新的文本语法符合条件 作为编译时常量

以及

NSString文本也是编译时常量,因为 编译器和库之间的耦合。有一个特别的 名为NSConstantString的NSString子类,具有固定的ivar布局:

这种紧密耦合有很多优点,比如产生合法的全球 变量初始值设定项,并且无需运行额外代码来构建 对象在运行时。然而,也有很大的缺点。这个 NSConstantString布局是永久设置的。必须维持这个等级 完全使用该数据布局,因为该数据布局已烘焙到 成千上万的第三方应用程序。如果苹果改变了布局,那么 第三方应用程序将崩溃,因为它们包含NSConstantString 具有旧布局的对象

如果NSArray文本是编译时常量,则需要 是一个类似的NSConstantArray类,具有 编译器可以生成,并且必须对其进行维护 与其他NSArray实现分开。这样的代码无法运行 在没有此NSConstantArray类的旧操作系统上。相同的 对于新文本可以访问的其他类存在问题 生产

这在NSNumber文本的情况下特别有趣。 Lion引入了标记指针,允许NSNumber的内容 直接嵌入指针中,无需 分离动态分配的对象。如果编译器发出标记 指针,它们的格式永远不会改变,并且与旧的 操作系统版本将丢失。如果编译器发出常量NSNumber 对象,则NSNumber文本将与 其他NSN数字,可能会对性能造成重大影响

相反,编译器只是向框架发出调用, 完全按照手动方式构建对象。 这会导致运行时受到一些影响,但不会比构建更糟糕 他们自己不需要新的语法,并且使一个更干净 设计


我也想知道这一点,除了历史原因,我想不出有什么好的理由一个有效而另一个无效。我的猜测是,让它工作并不是很重要。不可变和“编译时”是两件不同的事情。@TonyMkenu,谢谢Tony:)你把这个变成了个人的@vikingosegundo。奇怪的是,我觉得
@“a”
只是像
[NSString withutf8string:“a”