Ошибка компилятора: "Инициализатор не является константой времени компиляции"

При компиляции этого кода я получаю ошибку "элемент инициализации не является константой времени компиляции". Может кто-нибудь объяснить, почему?

#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

Ответ 1

Когда вы определяете переменную вне области действия функции, это значение переменной фактически записывается в ваш исполняемый файл. Это означает, что вы можете использовать только постоянное значение. Поскольку вы не знаете все о среде выполнения во время компиляции (какие классы доступны, какова их структура и т.д.), Вы не можете создавать объектные объекты c до выполнения, за исключением постоянных строк, которым заданы конкретные структуры и гарантированно останется таким образом. Что вам нужно сделать, это инициализировать переменную до нуля и использовать +initialize для создания вашего изображения. initialize - это метод класса, который будет вызываться до вызова любого другого метода в ваш класс.

Пример:

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

Ответ 2

Глобальная переменная должна быть инициализирована с постоянным значением, например 4 или 0.0 или @"constant string" или nil. Конструктор объекта, такой как init, не возвращает постоянное значение.

Если вы хотите иметь глобальную переменную, вы должны инициализировать ее до nil, а затем вернуть ее с помощью метода класса:

NSImage *segment = nil;

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

Ответ 3

Потому что вы просите компилятор инициализировать статическую переменную с кодом, который по своей сути является динамическим.

Ответ 4

Причина в том, что вы определяете свой imageSegment вне функции в исходном коде (статическая переменная).

В таких случаях инициализация не может включать выполнение кода, например вызов функции или распределение класса. Инициализатор должен быть константой, значение которой известно во время компиляции.

Затем вы можете инициализировать свою статическую переменную внутри вашего метода init (если вы отложите ее объявление до init).

Ответ 5

Вы можете указать #define макрос, как показано ниже. Компилятор заменит "IMAGE_SEGMENT" своим значением перед компиляцией. Хотя вы достигнете определения глобального поиска для вашего массива, это не то же самое, что глобальная переменная. Когда макрос расширяется, он работает так же, как встроенный код, и каждый раз создается новое изображение. Поэтому, если вы будете осторожны в том, где используете макрос, вы бы эффективно достигли создания глобальной переменной.

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

Затем используйте его там, где вам это нужно, как показано ниже. Каждый раз, когда выполняется следующий код, создается новый объект с новым указателем памяти.

imageSegment = IMAGE_SEGMENT