iOS - кодирование / декодирование перечислений - сбой при доступе после повторного запуска - PullRequest
2 голосов
/ 24 февраля 2011

Что я делаю не так? Правильно ли я кодирую / декодирую тип enum?

Интерфейс GameSettings:

typedef enum {
    CatWhite = 0,
    CatBlack = 1,
    CatOrange = 2
} CatColor;

...
CatColor catColor;
...
@property CatColor catColor;

Реализация GameSettings:

@synthesize catColor;

...

+ (GameSettings*)GetInstance
{
    if (sharedSingleton == nil) {
        sharedSingleton = [[super allocWithZone:NULL] init];
        sharedSingleton.catColor = CatWhite;
    }
    return sharedSingleton;
}
    -(void)encodeWithCoder:(NSCoder *)coder {
        [coder encodeInt:self.catColor forKey:@"CatColor"];
    }

    -(id)initWithCoder:(NSCoder *)coder {
        if((self = [super init])) {
            self.catColor = [coder decodeIntForKey:@"CatColor"];
        }
NSLog(@"initWithCoder: %d", self.catColor); //this logs the correct int
        return self;
    }

AppDidFinishLaunching:

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSData *data = [defaults objectForKey:@"GameSettings"];
        GameSettings *gGameData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        if(gGameData != NULL) {
            GameSettings *settings = [GameSettings GetInstance];
            settings.catColor = gGameData.catColor;

        }else {
            GameSettings *settings = [GameSettings GetInstance];
            settings.catColor = CatWhite;
        }
        ...
    }

Сохранить настройки:

GameSettings* settings = [GameSettings GetInstance];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:settings];
[defaults setObject:data forKey:@"GameSettings"];
[defaults synchronize];

Сбой (программа получила сигнал: «EXC_BAD_ACCESS») происходит, когда я перезапускаю приложение и пытаюсь получить доступ к настройкам игры:

GameSettings* settings = [GameSettings GetInstance];
NSLog(@"settings: %d", settings); //EXC_BAD_ACCESS
NSLog(@"catColor: %d", settings.catColor); //EXC_BAD_ACCESS

Почему я не могу получить доступ к синглтону GameSettings после перезапуска?

Ответы [ 2 ]

0 голосов
/ 24 февраля 2011

Наконец-то понял это. GameSettings был освобожден, потому что NSKeyedUnarchiver автоматически выпускал его:

GameSettings *gGameData = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Исправлено:

GameSettings *gGameData = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain];
0 голосов
/ 24 февраля 2011

Вы уверены, что хотите использовать там приложение applicationDidFinish?Когда вы воскрешаете программу, она может вызывать awakeFromNib вместо applicationDidFinishLaunching (источник: http://www.cimgf.com/2008/03/26/cocoa-tutorial-awakefromnib-vs-applicationdidfinishlaunching/).

...