Инициализация статического одноэлементного объекта с помощью NSCoder

Я работаю над приложением для iPhone и сталкиваюсь с некоторыми проблемами с моим общим синглтон-классом. Я использую общий синглтон для хранения двух переменныхint gameRuns а также int totalScore"gamRuns" просто увеличивается каждый раз, когда пользователь загружает приложение, и "totalScore" очевиден:D

проблема заключается в следующем, я загружаю singleton и init, используя свой собственный метод, когда приложение загружается с использованием этого кода:

+ (SingletonLevelState*)sharedLevelStateInstance {

static SingletonLevelState *sharedLevelStateInstance;

@synchronized(self) {
    if(!sharedLevelStateInstance) {
        //Init a singleton
        sharedLevelStateInstance = [[SingletonLevelState alloc] init];
        sharedLevelStateInstance->gameRuns = 1;
        sharedLevelStateInstance->totalScore = 0;
    }
}
return sharedLevelStateInstance;
}

Это прекрасно работает, так как я могу ссылаться на этот класс из любого другого класса и всегда получать указатель на тот же объект, поэтому он отлично работает из других объектов:

sharedLevelState = [SingletonLevelState sharedLevelStateInstance];
sharedLevelStateInstance.gameRuns++;

Теперь я добавил протокол NSCoder и добавил два метода initWithCoder а также encodeWithCoder следующее:

- (void) encodeWithCoder: (NSCoder *)coder
{
    //encode level data
    [coder encodeInt:self->gameRuns forKey:@"gameRuns"];
    [coder encodeInt:self->totalScore forKey:@"totalScore"];
}
- (id) initWithCoder: (NSCoder *) coder
{
    if(self = [super init]){
        self->gameRuns = [coder decodeIntForKey:@"gameRuns"];
        self->totalScore = [coder decodeIntForKey:@"totalScore"];
    }
    return self;
}

Теперь, когда приложение загружается, я проверяю, есть ли у нас уже сохраненное состояние, если оно существует, я просто разархивирую класс с этим файлом, если нет, я инициирую этот класс, используя мой пользовательский метод выше, затем устанавливаю его значения по умолчанию, кодирую это в файл, поэтому у нас есть сохраненное состояние, вот код:

 //Load Level state
sharedLevelStateInstance = [SingletonLevelState sharedLevelStateInstance];

//Check if file is saved
NSFileManager *fm = [[NSFileManager alloc] init];
NSString *gameStatePath = [NSString stringWithString:[self getSavePath]];

if([fm fileExistsAtPath:gameStatePath]){
    [self loadState];
    sharedLevelStateInstance.gameRuns = sharedLevelStateInstance.gameRuns+1;
    NSLog(@"Loaded %d times", [sharedLevelStateInstance gameRuns]);
}
[fm release];

Теперь последняя строка в операторе if работает отлично, она увеличивается каждый раз, когда я загружаю приложение, как ожидалось, и я чувствую себя действительно счастливым, лол.

Однако проблема возникает, когда я пытаюсь получить ссылку на синглтон в другом классе, выполнив следующие действия:

sharedLevelStateInstance = [SingletonLevelState sharedLevelStateInstance];
NSLog(@"Played: %d times", sharedLevelStateInstance.gameRuns);

Это всегда отсчитывает до 1, я знаю, что происходит, но я не судюсь, какой лучший способ решить это, когда я initWithCoder Синглтон, он не возвращает статический объект, он создает новый, когда я sharedLevelStateInstance, он вызывает мой первый пользовательский метод, инициализируя его по умолчанию в жестком коде.

Так что Stackru, не могли бы вы мне помочь?!

Мне просто нужно знать, как лучше всего получить ссылку на один и тот же объект без выделения нового каждый раз, когда я initWithCoder!

Спасибо:)

1 ответ

Решение

Итак, ваш код должен выглядеть примерно так:

if(self = [[SingletonLevelState sharedLevelStateInstance] retain])

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

Другие вопросы по тегам