2

Я работаю над приложением iPhone и сталкиваюсь с некоторыми проблемами с моим общим классом singleton. Я использую общий синглтон для хранения двух переменных int gameRuns и int totalScore «gamRuns» только с шагом каждый раз, когда пользователь загружает приложение, и «totalScore» очевидна: DИнициализация статического одноэлементного объекта с помощью NSCoder

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

+ (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 работает p erfectly, он увеличивается каждый раз, когда я загружаю приложение, как ожидалось, и Я чувствую себя очень счастливым lol.

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

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

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

So StackOverflow, не могли бы вы помочь мне?

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

Спасибо :)

ответ

2

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

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

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

+0

Ahhh отлично, вы только что спасли мой день :) –

+0

@ MostafaTorbjørnBerg не проблема, просто не забудьте принять ответ :) –

+0

Done :) Еще раз спасибо! –

Смежные вопросы