2012-04-29 3 views
0

Я думаю, что я галлюцинирую. Я пытаюсь добавить некоторую настойчивость в свою игру Concentration-lke. Я хотел бы отслеживать высокие баллы. Некоторое время назад я частично работал над этим, и теперь все прошло с kablooie (я думаю, что это правильная терминология iOS). Теперь мой allHighScores NSMutablearray внезапно становится CALayer. Я использую архивирование NSKeyed. У меня есть точка останова в моем файле до того, как allHighScores загрузится с данными. При переходе через приложение allHighScores существует как NSMutableArray, а затем на следующем этапе он становится CA-слоем. А?Мой NSMutableArray внезапно становится CALayer

-(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. Я очень смущен.

Я попытался добавить сохранение в инструкцию, но это не помогло.

Вот мой код кодирования/декодирования:

-(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;} 

UPDATE: Программа падает, когда «highscores.archive» файл уже существует и называется сохранить снова. Я могу запустить приложение, обратите внимание на высокие оценки - они там и извлекаться счастливо, но сохранить код:

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

вызывает EXC_BAD_ACCESS. Путь прав, так что все-таки allHighScores нет.

+0

Вы используете ARC? – joerick

+0

Можете ли вы показать нам, как вы реализуете протокол NSCoding в 'FlipHighScore', или как бы то ни было имя класса? – mbm29414

+0

Попробуйте это 'NSLog (@" unarchived class% @ ", NSStringFromClass ([allHighScores class])); и обратите внимание на результат. – CodaFi

ответ

2

Проблема в том, что вы не сохраняете результаты разборки. Согласно Basic Memory Management Rules, метод по имени +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])) { 
+0

Спасибо! Я добавил сохранение и не изменилось поведение. Я не думал, что мне нужно сохранить, поскольку я использовал ARC. –

+0

@ AugustusS-R: Я не понимал, что вы используете ARC. Вы все еще нуждаетесь в '-mutableCopy', хотя, если вам нужен изменяемый массив. –

+0

Спасибо за мысль, Кевин! allHighScores все еще становится CALayer (что, очевидно, плохо ...) –

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

Edit/Update: Итак, вот две версии того, что я на самом деле предназначены в приведенном выше примере (я предполагаю, что здесь, что его Ивар 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; 
} 
+2

Cargo-культовое программирование в лучшем виде. Присвоение ивару, а затем вызов того же сеттера? Это бессмысленно. –

+0

return self; также отсутствует. – MrMage

+0

Если, конечно, поскольку он использует ARC, объект не сохраняется, просто назначая ivar. У него странная проблема. Я хотел убедиться, что мы проверили все основы. Спасибо всем, кто проголосовал за честную попытку помочь !!! Чувствуете ли вы себя лучше? – mbm29414