我的NSMutableArray突然变成了CALayer

时间:2012-04-29 21:06:38

标签: ios nskeyedarchiver

我想我是幻觉。我试图为我的Concentration-lke游戏添加一些持久性。我想跟踪高分。我今天已经部分工作了一段时间,现在它已经全部消失了kablooie(我认为这是正确的iOS术语)。现在,我的allHighScores NSMutablearray突然变成了CALayer。我正在使用NSKeyed Archiving。在allHighScores加载数据之前,我的文件中有一个断点。当单步执行应用程序时,allHighScores作为NSMutableArray存在 - 然后,在下一步,它突然变为CA层。咦?

-(id)init 
{
    self = [super init];
    if (self) {
        NSString *path = [self flipScoreArchivePath];
        NSLog(@"Path is %@", path);
        allHighScores = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
        if (!allHighScores)  {
        allHighScores = [[NSMutableArray alloc] init];
        }
    }
    return self;
}


+(FlipHighScoreStore *)sharedStore {
    static FlipHighScoreStore *sharedStore = nil;
    if (!sharedStore) {
        sharedStore = [[super allocWithZone:nil]init];
    }
    return sharedStore;
}

不知何故,调用NSKeyedUnarchiver会将我的allHighScores从NSMutableArray更改为CALayer。我很困惑。

我尝试在unarchiving指令中添加一个retain,但这没有帮助。

这是我的编码/解码代码:

-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.themeChosen forKey:@"themeChosen"];
[aCoder encodeInt:self.highScore forKey:@"highScore"];
[aCoder encodeInt:self.scoreStartLevel forKey:@"scoreStartLevel"];
[aCoder encodeInt:self.scoreFinishLevel forKey:@"scoreFinishLevel"];
[aCoder encodeObject:scoreDateCreated forKey:@"scoreDateCreated"];}

-(id)initWithCoder:(NSCoder *)aDecoder {
if (self) {
    self.themeChosen = [aDecoder decodeObjectForKey:@"themeChosen"];
    self.highScore = [aDecoder decodeIntForKey:@"highScore"];
    self.scoreStartLevel = [aDecoder decodeIntForKey:@"scoreStartLevel"];
    self.scoreFinishLevel = [aDecoder decodeIntForKey:@"scoreFinishLevel"];
    scoreDateCreated = [aDecoder decodeObjectForKey:@"scoreDateCreated"];
}
return self;}

更新:当“highscores.archive”文件已经存在并再次调用save时,程序崩溃。我可以启动应用程序,查看高分 - 他们在那里并愉快地检索,但保存代码:

-(BOOL)saveHighScores {
NSString *path = [self flipScoreArchivePath];
return [NSKeyedArchiver archiveRootObject:allHighScores toFile:path];}

导致EXC_BAD_ACCESS。路径是正确的,所以allHighScores不是。

2 个答案:

答案 0 :(得分:2)

这里的问题是你没有保留unarchiving的结果。根据{{​​3}},名为+unarchiveObjectWithFile:的方法将返回一个自动释放的对象。因此,由于您将它放入ivar中,您需要保留此对象,否则它将从您下面取消分配。

虽然在你的情况下,因为你想要一个可变数组,你实际上需要调用-mutableCopy,因为NSKeyedUnarchive只会给你一个不可变的数组。

-(id)init {
    if ((self = [super init])) {
        NSString *path = [self flipScoreArchivePath];
        NSLog(@"Path is %@", path);
        allHighScores = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] mutableCopy];
        if (!allHighScores) {
            allHighScores = [[NSMutableArray alloc] init];
        }
    }
    return self;
}

你的-initWithCoder:没有打电话给超级。你需要说

if ((self = [super initWithCoder:aDecoder])) {

答案 1 :(得分:-3)

你试过这个吗?

-(id)init { 
    if ((self = [super init])) {
        NSString *path = [self flipScoreArchivePath];
        NSLog(@"Path is %@", path);
        allHighScores = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] mutableCopy];
        if (!allHighScores) {
            allHighScores = [[NSMutableArray alloc] init];
        }
        // All-important new line....
        [self setAllHighScores:allHighScores];
    }
    return self;
}

修改/更新 的 所以,这是我在上面的例子中实际意图的两个版本(我假设他的ivar allHighScores具有相应的属性):

-(id)init { 
    if ((self = [super init])) {
        NSString *path = [self flipScoreArchivePath];
        NSLog(@"Path is %@", path);
        self.allHighScores = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] mutableCopy];
        if (!self.allHighScores) {
            self.allHighScores = [[NSMutableArray alloc] init];
        }
    }
    return self;
}

这就是我实际做的方式:

-(id)init { 
    if ((self = [super init])) {
        NSMutableArray *arr = [[NSKeyedUnarchiver unarchiveObjectWithFile:[self flipScoreArchivePath]] mutableCopy];
        if (!arr) arr = [[NSMutableArray alloc] init];
        [self setAllHighScores:arr];
    }
    return self;
}