Errore del compilatore: “l’elemento di inizializzazione non è una costante in fase di compilazione”

Quando compilo questo codice, ottengo l’errore “l’elemento di inizializzazione non è una costante in fase di compilazione”. Qualcuno può spiegare perché?

#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 

Quando si definisce una variabile al di fuori dell’ambito di una funzione, il valore di tale variabile viene effettivamente scritto nel file eseguibile. Ciò significa che puoi utilizzare solo un valore costante. Dato che non si sa tutto sull’ambiente di runtime al momento della compilazione (quali classi sono disponibili, qual è la loro struttura, ecc.), Non è ansible creare oggetti oggettivi fino al runtime, ad eccezione delle stringhe costanti, a cui viene assegnato uno specifico struttura e garantito per rimanere in quel modo. Quello che dovresti fare è inizializzare la variabile su nil e usare +initialize per creare la tua immagine. initialize è un metodo di class che verrà chiamato prima che qualsiasi altro metodo venga chiamato sulla class.

Esempio:

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

Una variabile globale deve essere inizializzata su un valore costante, come 4 o 0.0 o @"constant string" o nil . Un costruttore di oggetti, come init , non restituisce un valore costante.

Se si desidera avere una variabile globale, è necessario inizializzarla su nil e quindi restituirla utilizzando un metodo di class:

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

Perché stai chiedendo al compilatore di inizializzare una variabile statica con codice intrinsecamente dinamico.

Il motivo è che stai definendo il tuo imageSegment al di fuori di una funzione nel tuo codice sorgente (variabile statica).

In tali casi, l’inizializzazione non può includere l’esecuzione del codice, come chiamare una funzione o assegnare una class. Initializer deve essere una costante il cui valore è noto al momento della compilazione.

È quindi ansible inizializzare la variabile statica all’interno del metodo init (se si rinvia la sua dichiarazione a init).

Puoi sicuramente # definire una macro come mostrato di seguito. Il compilatore sostituirà “IMAGE_SEGMENT” con il suo valore prima della compilazione. Mentre raggiungerai la definizione di una ricerca globale per il tuo array, non è la stessa cosa di una variabile globale. Quando la macro è espansa, funziona come il codice inline e quindi ogni volta viene creata una nuova immagine. Quindi, se stai attento a dove usi la macro, avresti effettivamente realizzato la creazione di una variabile globale.

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

Quindi usalo dove ti serve come mostrato di seguito. Ogni volta che viene eseguito il codice sottostante, viene creato un nuovo object con un nuovo puntatore di memoria.

 imageSegment = IMAGE_SEGMENT