web-dev-qa-db-de.com

Compiler-Fehler: "Initialisierungselement ist keine Konstante zur Kompilierungszeit"

Beim Kompilieren dieses Codes erhalte ich die Fehlermeldung "Das Initialisierungselement ist keine Konstante zur Kompilierungszeit". Kann mir jemand erklären warum?

#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
73
Nick

Wenn Sie eine Variable außerhalb des Bereichs einer Funktion definieren, wird der Wert dieser Variablen tatsächlich in Ihre ausführbare Datei geschrieben. Das heißt, Sie können nur einen konstanten Wert verwenden. Da Sie zur Kompilierungszeit nicht alles über die Laufzeitumgebung wissen (welche Klassen sind verfügbar, wie ist ihre Struktur usw.), können Sie Objective C-Objekte erst zur Laufzeit erstellen, mit Ausnahme von konstanten Zeichenfolgen, die eine bestimmte Eigenschaft haben Struktur und garantiert so zu bleiben. Was Sie tun sollten, ist die Variable auf Null zu initialisieren und +initialize, um Ihr Bild zu erstellen. initialize ist eine Klassenmethode, die aufgerufen wird, bevor eine andere Methode in Ihrer Klasse aufgerufen wird.

Beispiel:

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

Eine globale Variable muss mit einem konstanten Wert wie 4 Oder 0.0 Oder @"constant string" Oder nil initialisiert werden. Ein Objektkonstruktor wie init gibt keinen konstanten Wert zurück.

Wenn Sie eine globale Variable haben möchten, sollten Sie sie mit nil initialisieren und dann mit einer Klassenmethode zurückgeben:

NSImage *segment = nil;

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

Weil Sie den Compiler auffordern, eine statische Variable mit Code zu initialisieren, der von Natur aus dynamisch ist.

10
bbum

Der Grund ist, dass Sie Ihr imageSegment außerhalb einer Funktion in Ihrem Quellcode (statische Variable) definieren.

In solchen Fällen kann die Initialisierung nicht die Ausführung von Code umfassen, z. B. das Aufrufen einer Funktion oder das Zuweisen einer Klasse. Der Initialisierer muss eine Konstante sein, deren Wert zur Kompilierungszeit bekannt ist.

Sie können dann Ihre statische Variable innerhalb Ihrer init -Methode initialisieren (wenn Sie ihre Deklaration auf init verschieben).

5
sergio

Sie können natürlich ein Makro wie unten gezeigt definieren. Der Compiler ersetzt "IMAGE_SEGMENT" vor dem Kompilieren durch seinen Wert. Während Sie eine globale Suche für Ihr Array definieren, ist dies nicht dasselbe wie eine globale Variable. Wenn das Makro erweitert wird, funktioniert es genau wie Inline-Code, sodass jedes Mal ein neues Bild erstellt wird. Wenn Sie also vorsichtig sind, wo Sie das Makro verwenden, hätten Sie effektiv eine globale Variable erstellt.

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

Verwenden Sie es dann dort, wo Sie es benötigen (siehe unten). Jedes Mal, wenn der folgende Code ausgeführt wird, wird ein neues Objekt mit einem neuen Speicherzeiger erstellt.

imageSegment = IMAGE_SEGMENT
3