【问题标题】:"Initializer element is not a compile-time constant" why?“初始化元素不是编译时常量”为什么?
【发布时间】:2012-08-31 13:09:42
【问题描述】:

我有这个代码:

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

编译器抱怨说:“初始化器元素不是编译时常量”。当我将“静态”添加到 localArray 时发生了这种情况。但是为什么呢?

【问题讨论】:

标签: objective-c ios xcode


【解决方案1】:

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

要么将您的代码编译为 Objective-C++,要么将其重构为如下内容:

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

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

【讨论】:

  • 我建议使用dispatch_once() 来初始化localArray。它是线程安全且非常高效的。
【解决方案2】:

您只是不能使用将在运行时知道/修改的非静态值来初始化静态变量。

你可能应该这样做:

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

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

不过,请注意,如果使用不当,使用静态变量可能会导致错误行为,因此如果您对这些感到不安,您可能不应该使用它们。

【讨论】:

    猜你喜欢
    • 2014-02-18
    • 1970-01-01
    • 2011-09-02
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    相关资源
    最近更新 更多