2012-09-06 67 views
13

我有这样的代码:“初始化元素不是编译时常量”为什么?

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

编译器会抱怨说:“初始值元素不是一个编译时间常数”。当我将“static”添加到localArray时发生了这种情况。但为什么?

+0

http://stackoverflow.com/q/6143107/94687是同样的问题。在你的问题中唯一特别的是将static关键字明确地添加到函数体内的变量中(但是这必须等同于在全局范围内具有变量,就像在该问题中那样)。 –

回答

28

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

要么编译代码的Objective-C++,或者重构弄成这个样子:

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

这是相当类似,编译器会在引擎盖下生成一个static变量和初始化代码非编译时常量(实际上,它将使用第二个全局标志,指示该值是否已初始化,而不是像这里使用哨兵值nil;在这种情况下,我们假设localArray永远不会是nil)。如果你愿意,你可以检查你的编译器的反汇编。

+2

我建议使用'dispatch_once()'初始化'localArray'。这是线程安全和非常有效的。 – bbum

5

你只是不能初始化一个静态变量,它具有一个在运行时将被知道/修改的非静态值。

你或许应该做这样的事情:

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

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

尽管如此,请注意使用静态变量会导致错误行为,如果做得不好,所以如果您对这些行为感到不安,您应该不要使用它们。

+2

+1“第一条指令将在您的应用生命周期中执行一次。” – Philip007

相关问题