iOS - 编码/解码枚举 - 重新启动后访问崩溃

发布于 2024-10-18 23:20:33 字数 2090 浏览 9 评论 0原文

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

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

What am I doing wrong? Am I encoding/decoding the enum type properly?

GameSettings interface:

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

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

GameSettings implementation:

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

Save settings:

GameSettings* settings = [GameSettings GetInstance];

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

The crash (Program received signal: “EXC_BAD_ACCESS”) comes when I re-launch the app and try to access the game settings:

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

Why can't I access the GameSettings singleton after a re-launch?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小红帽 2024-10-25 23:20:33

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

Are you sure you want to use applicationDidFinishLaunching there? When you resurrect the program, it may be invoking awakeFromNib instead of applicationDidFinishLaunching (source: http://www.cimgf.com/2008/03/26/cocoa-tutorial-awakefromnib-vs-applicationdidfinishlaunching/ ).

没有心的人 2024-10-25 23:20:33

终于明白了这一点。 GameSettings 被释放,因为 NSKeyedUnarchiver 正在自动释放它:

GameSettings *gGameData = [NSKeyedUnarchiver unarchiveObjectWithData:data];

修复:

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

Finally figured this out. GameSettings was getting deallocated because NSKeyedUnarchiver was autoreleasing it:

GameSettings *gGameData = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Fix:

GameSettings *gGameData = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文