【问题标题】:iOS - encoding/decoding enums - crash on accessing after relaunchiOS - 编码/解码枚举 - 重新启动后访问时崩溃
【发布时间】:2011-02-24 01:20:19
【问题描述】:

我做错了什么?我是否正确编码/解码枚举类型?

游戏设置界面:

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 单例?

【问题讨论】:

  • 我假设 GameSettings 继承自 NSObject,但情况是这样吗?图我应该问。也没有真正帮助您修剪界面的一些部分使其大部分脱离上下文。另外,GetInstance 长什么样子?
  • 你能从调试器控制台发布堆栈跟踪吗?
  • @nil,是的,它继承自 NSObject。我已经在上面添加了 Get Instance 方法。

标签: ios encoding nsuserdefaults nskeyedarchiver


【解决方案1】:

您确定要在那里使用 applicationDidFinishLaunching 吗?当您重新启动程序时,它可能会调用 awakeFromNib 而不是 applicationDidFinishLaunching(来源:http://www.cimgf.com/2008/03/26/cocoa-tutorial-awakefromnib-vs-applicationdidfinishlaunching/)。

【讨论】:

    【解决方案2】:

    终于想通了。 GameSettings 正在被释放,因为 NSKeyedUnarchiver 正在自动释放它:

    GameSettings *gGameData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    

    修复:

    GameSettings *gGameData = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain];
    

    【讨论】:

      猜你喜欢
      • 2019-01-06
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      相关资源
      最近更新 更多