Erro do compilador: “elemento inicializador não é uma constante de tempo de compilation”

Ao compilar este código, recebo o erro “elemento inicializador não é uma constante de tempo de compilation”. Alguém pode 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 

Quando você define uma variável fora do escopo de uma function, o valor dessa variável é realmente gravado em seu arquivo executável. Isso significa que você só pode usar um valor constante. Como você não sabe tudo sobre o ambiente de tempo de execução em tempo de compilation (quais classs estão disponíveis, qual é sua estrutura, etc.), não é possível criar objects c objectives até o tempo de execução, com exceção de sequências constantes, que recebem um específico estrutura e garantido para ficar assim. O que você deve fazer é inicializar a variável para nil e usar +initialize para criar sua imagem. initialize é um método de class que será chamado antes que qualquer outro método seja chamado em sua class.

Exemplo:

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

Uma variável global deve ser inicializada para um valor constante, como 4 ou 0.0 ou @"constant string" ou nil . Um construtor de object, como init , não retorna um valor constante.

Se você quer ter uma variável global, você deve inicializá-la com nil e depois retorná-la usando um método de class:

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

Porque você está pedindo ao compilador para inicializar uma variável estática com código que é inerentemente dynamic.

A razão é que você está definindo seu imageSegment fora de uma function em seu código-fonte (variável estática).

Em tais casos, a boot não pode include a execução de código, como chamar uma function ou alocar uma class. Inicializador deve ser uma constante cujo valor é conhecido em tempo de compilation.

Você pode então inicializar sua variável estática dentro de seu método init (se você adiar sua declaração para init).

Você pode certamente # definir uma macro como mostrado abaixo. O compilador replaceá “IMAGE_SEGMENT” por seu valor antes da compilation. Embora você consiga definir uma pesquisa global para sua matriz, ela não é igual a uma variável global. Quando a macro é expandida, ela funciona exatamente como o código embutido e, assim, uma nova imagem é criada a cada vez. Então, se você for cuidadoso em onde você usa a macro, você teria conseguido efetivamente criar uma variável global.

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

Em seguida, use-o onde você precisar, conforme mostrado abaixo. Cada vez que o código abaixo é executado, um novo object é criado com um novo ponteiro de memory.

 imageSegment = IMAGE_SEGMENT