0

I'm making a game using Cocos2d-iphone 2.1, and have encountered an error with NSCoding unarchiving implementation.

I've used the same pattern in my previous projects (made with UIKit), and everything worked perfetly. While when I'm implementing this pattern on cocos2d, it just doesn't work.

I have recreated the error on a sample project (which can be downloaded here https://www.dropbox.com/sh/30cyfczcxeyf8mr/uDcJiNYMdd ) and here's what I'm doing:

  1. I've created a simple singleton class "GameStore". Then I've created the "GameParameters" class which is a property of the singleton and conforms to NSCoding (therefore can be archived). In that class there's the "highscore" property of type int (for example) which I'd like to keep archived as a high score value.
  2. In the GameStore class I initialize the GameParameters instance for the first time, if there's an archived object - I unarchive it.
  3. In the "HelloWorldLayer" (which is a default cocos2d placeholder class) I call NSLog to display the "highscore" value and then set it to a new value
  4. In AppDelegate I call the "save data" method to archive data whenever the home button is pressed.

That's it. When I start the app for the first time, everything works well, and I save the data by pressing the home button. And when I start the app again, I run into random (as it seems) EXT_BAD_ACCESS errors... Sometimes when I'm getting the highscore value, sometimes when archiving it again.

Any idea what I might be doing wrong here?

Thanks!

GameStore class

Header file:

#import <Foundation/Foundation.h>

@class GameParameters;

@interface GameStore : NSObject

@property (retain, nonatomic) GameParameters * parameters;

+ (GameStore *) game;

- (void) saveData;

@end

Implementation file:

#import "GameStore.h"
#import "GameParameters.h"

static GameStore * game = nil;

@implementation GameStore

@synthesize parameters;

+ (GameStore *) game
{
    if (!game) game = [[super allocWithZone:nil] init];
    return game;
}

- (id) init
{
    if (game != nil) {
        return game;
    }

    self = [super init];

    if (self) {
        // Initialization

        // Try and load the "GameParameters" from archive
        parameters = [NSKeyedUnarchiver unarchiveObjectWithFile:[self archivePath]];
        NSLog(@"Highscore: %i",parameters.highscore);
        // If there's no archive, initialize the "GameParameters"
        if (!parameters) {
            parameters = [[GameParameters alloc] init];
            parameters.highscore = 12345;
        }
    }

    return self;
}

- (void) saveData
{
    [NSKeyedArchiver archiveRootObject:parameters toFile:[self archivePath]];
    NSLog(@"Data saved");
}

- (NSString *)archivePath
{
    NSArray * documentDirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString * documentDir = [documentDirs objectAtIndex:0];

    return [documentDir stringByAppendingPathComponent:@"hs.archive"];
}

@end

GameParameters class Header file:

#import <Foundation/Foundation.h>

@interface GameParameters : NSObject <NSCoding>

@property (nonatomic, assign) int highscore;

@end

Implementation file:

#import "GameParameters.h"

@implementation GameParameters
@synthesize highscore;

- (id) initWithCoder:(NSCoder *)aDecoder
{
    highscore = [aDecoder decodeIntForKey:@"1"];

    return self;
}

- (void) encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeInt:highscore forKey:@"1"];
}

@end
Andrey
  • 13
  • 3
  • what line is the error on? anything in the log? add an exception breakpoint – CodeSmile May 03 '14 at 16:13
  • Hi! For example, right now the error is on the line: [NSKeyedArchiver archiveRootObject:parameters toFile:[self archivePath]]; EXC_BAD_ACCESS. Nothing definite in the log. The GameParameters class is definitely allocated in memory. Before that, the EXC_BAD_ACCESS occured after unarchiving the class. – Andrey May 03 '14 at 16:23
  • Now, after I've rearchived the file, it throws me an exception "Unrecognized selector..." on the NSLog(@"Highscore: %i",parameters.highscore); line. Apparently, the GameParameters class this time had been unarchived with the type NSString and contains @"pt" string, which is bizarre to me – Andrey May 03 '14 at 16:30

0 Answers0