objective-c cocoa initialization compiler-errors global-variables

objective c - Error del compilador: "el elemento inicializador no es una constante en tiempo de compilaciĆ³n"



objective-c cocoa (5)

Al compilar este código, aparece el error "el elemento inicializador no es una constante en tiempo de compilación". ¿Alguien puede explicar por qué?

#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


Cuando define una variable fuera del alcance de una función, el valor de dicha variable se escribe realmente en su archivo ejecutable. Esto significa que solo puede usar un valor constante. Como no sabe todo sobre el entorno de tiempo de ejecución en tiempo de compilación (qué clases están disponibles, cuál es su estructura, etc.), no puede crear objetos objetivo c hasta el tiempo de ejecución, con la excepción de cadenas constantes, a las que se asigna un valor específico estructura y garantizado para permanecer de esa manera. Lo que debe hacer es inicializar la variable a cero y usar +initialize para crear su imagen. initialize es un método de clase que se llamará antes de invocar cualquier otro método en su clase.

Ejemplo:

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; }


Definitivamente puede # definir una macro como se muestra a continuación. El compilador reemplazará "IMAGE_SEGMENT" por su valor antes de la compilación. Si bien logrará definir una búsqueda global para su matriz, no es lo mismo que una variable global. Cuando la macro se expande, funciona igual que el código en línea y, por lo tanto, se crea una nueva imagen cada vez. Entonces, si tiene cuidado con el lugar donde usa la macro, entonces habría logrado crear una variable global.

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

Luego, úselo donde lo necesite, como se muestra a continuación. Cada vez que se ejecuta el código siguiente, se crea un nuevo objeto con un nuevo puntero de memoria.

imageSegment = IMAGE_SEGMENT


La razón es que estás definiendo tu imageSegment fuera de una función en tu código fuente (variable estática).

En tales casos, la inicialización no puede incluir la ejecución del código, como llamar a una función o asignar una clase. Inicializador debe ser una constante cuyo valor se conoce en tiempo de compilación.

Luego puede inicializar su variable estática dentro de su método init (si pospone su declaración para iniciar).


Porque le está pidiendo al compilador que inicialice una variable estática con un código que es inherentemente dinámico.


Una variable global debe inicializarse a un valor constante, como 4 o 0.0 o @"constant string" o nil . Un constructor de objetos, como init , no devuelve un valor constante.

Si desea tener una variable global, debe inicializarla en nil y luego devolverla usando un método de clase:

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