“Initializer元素不是编译时常量”为什么?

时间:2012-09-06 16:48:21

标签: objective-c ios xcode

我有这段代码:

- (NSString *) calculate: (uint) position {
    static NSArray * localArray = [NSArray arrayWithArray: self.container.objects ];
    // some un related code
    return obj;
}

编译器抱怨说:“Initializer元素不是编译时常量”。它发生在我向localArray添加“static”时。但为什么呢?

2 个答案:

答案 0 :(得分:28)

因为[NSArray arrayWithArray: self.container.objects ]不是编译时常量,所以它是必须在运行时计算的表达式。在C和Objective-C中,函数内的static变量必须用编译时常量初始化,而C ++和Objective-C ++更宽松,允许非编译时常量。 / p>

将代码编译为Objective-C ++,或者将其重构为以下内容:

static NSArray *localArray = nil;
if (localArray == nil)
    localArray = [NSArray arrayWithArray: self.container.objects ];

这与编译器为无法编译时使用非编译时常量初始化的static变量生成的代码非常相似(实际上,它会使用第二个全局标志来指示是否值已初始化,而不是像nil这样使用标记值;在这种情况下,我们假设localArray永远不会是nil)。如果需要,可以查看编译器的反汇编。

答案 1 :(得分:5)

您无法使用在运行时已知/修改的非静态值初始化静态变量。

你应该做这样的事情:

static NSArray *localArray = nil;
localArray = ...;

第一条指令将在您的应用生命周期中执行一次。 每次调用calculate:方法时都会执行第二条指令。

尽管如此,请注意使用静态变量如果操作不当会导致错误的行为这一事实,如果你对这些行为感到不安,你可能不应该使用它们。