编译错误:“初始化元素不是编译时常量”

编译这段代码时,出现“初始化元素不是编译时常量”的错误。 谁能解释为什么?

#import "PreferencesController.h" @implementation PreferencesController - (id)init { self = [super init]; if (self) { // Initialization code here. } return self; } NSImage* imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];//error here 

当你在一个函数的范围之外定义一个variables时,这个variables的值实际上被写入到你的可执行文件中。 这意味着你只能使用一个常数值。 由于在编译时不了解运行时环境的所有信息(哪些类是可用的,它们的结构如何等),所以在运行时不能创build客观的c对象,除了常量string,结构,并保证保持这种方式。 你应该做的是初始化variables为零,并使用+initialize来创build您的图像。 initialize是一个类方法,将在您的类上调用任何其他方法之前调用。

例:

 NSImage *imageSegment = nil; + (void)initialize { if(!imageSegment) imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"]; } - (id)init {  self = [super init];  if (self) {    // Initialization code here.  }  return self; } 

一个全局variables必须被初始化为一个常数值,比如4或者0.0@"constant string"或者nil 。 对象构造函数(如init )不会返回一个常量值。

如果你想有一个全局variables,你应该初始化它nil ,然后使用类方法返回它:

 NSImage *segment = nil; + (NSImage *)imageSegment { if (segment == nil) segment = [[NSImage alloc] initWithContentsOfFile:@"/user/asd.jpg"]; return segment; } 

因为你要求编译器用固有的dynamic代码初始化一个静态variables。

原因是你正在源代码(静态variables)函数之外定义imageSegment

在这种情况下,初始化不能包含执行代码,如调用函数或分配类。 初始化器必须是一个在编译时已知的常量。

然后你可以初始化你的init方法中的静态variables(如果你推迟它的声明到init)。

你当然可以#定义一个macros,如下所示。 编译器将在编译之前用它的值replace“IMAGE_SEGMENT”。 虽然您将为数组定义全局查找,但它与全局variables不同。 当macros展开时,它就像embedded式代码一样工作,所以每次创build一个新的图像。 所以,如果你在使用macros的地方小心,那么你将有效地实现创build一个全局variables。

 #define IMAGE_SEGMENT [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"]; 

然后在需要的地方使用它,如下所示。 每次执行下面的代码时,都会使用新的内存指针创build一个新对象。

 imageSegment = IMAGE_SEGMENT