web-dev-qa-db-fra.com

Erreur du compilateur: "l'élément initializer n'est pas une constante de compilation"

Lors de la compilation de ce code, j'obtiens le message d'erreur "L'élément initializer n'est pas une constante de compilation". Quelqu'un peut-il expliquer pourquoi?

#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

Lorsque vous définissez une variable en dehors de la portée d'une fonction, sa valeur est réellement écrite dans votre fichier exécutable. Cela signifie que vous ne pouvez utiliser qu'une valeur constante. Etant donné que vous ne connaissez pas tout de l'environnement d'exécution au moment de la compilation (quelles classes sont disponibles, quelle est leur structure, etc.), vous ne pouvez pas créer d'objets Objective C avant l'exécution, à l'exception des chaînes constantes, qui sont associées à une chaîne spécifique. structure et garantie de rester ainsi. Ce que vous devez faire est d’initialiser la variable sur nil et d’utiliser +initialize pour créer votre image. initialize est une méthode de classe qui sera appelée avant qu'aucune autre méthode ne soit appelée sur votre classe.

Exemple:

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

Une variable globale doit être initialisée à une valeur constante, comme 4 ou 0.0 ou @"constant string" ou nil. Un constructeur d'objet, tel que init, ne renvoie pas de valeur constante.

Si vous voulez avoir une variable globale, vous devriez l'initialiser à nil puis la renvoyer en utilisant une méthode de classe:

NSImage *segment = nil;

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

Parce que vous demandez au compilateur d'initialiser une variable statique avec du code intrinsèquement dynamique.

10
bbum

La raison en est que vous définissez votre imageSegment en dehors d'une fonction de votre code source (variable statique).

Dans de tels cas, l'initialisation ne peut pas inclure l'exécution de code, comme appeler une fonction ou affecter une classe. L'initialiseur doit être une constante dont la valeur est connue au moment de la compilation.

Vous pouvez ensuite initialiser votre variable statique à l'intérieur de votre méthode init (si vous retardez sa déclaration à init).

5
sergio

Vous pouvez certainement # définir une macro comme indiqué ci-dessous. Le compilateur remplacera "IMAGE_SEGMENT" par sa valeur avant la compilation. Bien que vous parveniez à définir une recherche globale pour votre tableau, ce n'est pas la même chose qu'une variable globale. Lorsque la macro est développée, elle fonctionne comme le code en ligne et une nouvelle image est créée à chaque fois. Donc, si vous faites attention lorsque vous utilisez la macro, vous aurez effectivement réussi à créer une variable globale.

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

Ensuite, utilisez-le où vous en avez besoin, comme indiqué ci-dessous. Chaque fois que le code ci-dessous est exécuté, un nouvel objet est créé avec un nouveau pointeur de mémoire.

imageSegment = IMAGE_SEGMENT
3
Kris Subramanian