13

我有这个代码:

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

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

4

2 回答 2

30

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

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

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

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

于 2012-09-06T16:52:33.483 回答
5

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

你可能应该做这样的事情:

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

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

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

于 2012-09-06T16:53:05.483 回答