0

J'enregistre des données en utilisant une série de NSDictionaries, stockées dans un NSMutableArray et archivées en utilisant NSKeyedArchiver.Problème de lecture d'une chaîne d'un NSDictionary dans un NSMutableArray stocké à l'aide de NSKeyedArchiver

Je suis fondamentalement en essayant de sauver les états de plusieurs cas, la classe « brique », donc je l'ai mis en place une méthode getBlueprint comme celui-ci (version allégée)

-(id)getBlueprint 
{ 

    // NOTE: brickColor is a string 

NSDictionary *blueprint = [NSDictionary dictionaryWithObjectsAndKeys: 
     brickColor, @"color", 
       [NSNumber numberWithInt:rotation], @"rotation", 
     nil]; 
return blueprint; 

} 

Et je donc une autre méthode Cela crée une nouvelle instance de Brick avec un blueprint.

-(id)initWithBlueprint:(NSDictionary *)blueprint spriteSheet:(NSString *)ssheet 
    { 
    if((self == [super init])){ 

     brickColor = [blueprint objectForKey:@"color"]; 
     [self setColorOffset:brickColor]; 

     while(rotation != [[blueprint objectForKey:@"rotation"] intValue]){ 
     [self setRotation:90]; 
     } 
    } 

    return self; 

    } 

qui fonctionne quand je passe un plan « frais », mais pas quand je lis un plan à partir d'un fichier enregistré ... en quelque sorte. Par exemple, la rotation fonctionnera mais changera la couleur. Ainsi, alors que je peux lire la valeur de l'aide brickColor

NSLog(@"brick color %@", [blueprint objectForKey:@"color"]); 

si je tente quelque chose comme

if(brickColor == @"purple"){ 
    colorOffset = CGPointMake(72,36); 
    NSLog(@"Changed offset for -- %@ -- to %@", color, NSStringFromCGPoint(colorOffset)); 
} 

Et je sais que la couleur est pourpre, la condition ne retourne pas vrai. J'ai pensé qu'il se pourrait que NSKeyedUnarchiver ait changé une chaîne en quelque chose d'autre, mais le test suivant renvoie true.

if([color isKindOfClass:[NSString class]]){ 
    NSLog(@"%@ IS A STRING", color); 
}else{ 
    NSLog(@"!!!!! COLOR IS A NOT STRING !!!!!"); 
} 

Comme je l'ai dit, ce n'est pas un problème si je tente d'utiliser un fraîchement créé NSDictionary comme un plan, que lorsqu'un projet est archivé puis relue.

Alors, comme d'habitude , Je me demande si quelqu'un a des idées pour lesquelles cela pourrait se produire.

S'il est pertinent, voici comment les données sont stockées et reçues.

// Saving  
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 

    -(void)buildLevelData{ 

    levelData = [[NSMutableArray alloc] initWithCapacity:100]; 
    for(brickSprite *brick in spriteHolder.children){ 

     [levelData addObject:[brick getBlueprint]]; 

    } 

    } 



    -(void)saveLevel 
    { 
    [self buildLevelData]; 

    NSData *rawDat = [NSKeyedArchiver archivedDataWithRootObject:levelData]; 

    if([self writeApplicationData:rawDat toFile:saveFileName]){ 
     NSLog(@"Data Saved"); 
    }else{ 
     NSLog(@"ERROR SAVING LEVEL DATA!"); 
    } 
    [[Director sharedDirector] replaceScene:[MainMenu scene]]; 
    } 


    - (BOOL)writeApplicationData:(NSData *)data toFile:(NSString *)fileName { 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     if (!documentsDirectory) { 
      NSLog(@"Documents directory not found!"); 
      return NO; 
     } 
     NSString *appFile = [saveDir stringByAppendingPathComponent:fileName]; 
     return ([data writeToFile:appFile atomically:YES]); 
    } 

// Loading 
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
- (void) loadRandomMapFrom:(NSString *)dir 
{ 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *docsDir = [paths objectAtIndex:0]; 

if(!docsDir){ 
    NSLog(@"Cound Not Find Documents Directory When trying To Load Random Map"); 
    return; 
} 

dir = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@", dir]]; 

// we'll also set the file name here. 
NSArray *existingFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil]; 

// get last file for this test 
NSString *filePath = [dir stringByAppendingPathComponent:[existingFiles objectAtIndex:([existingFiles count] - 1)]]; 

NSMutableArray *levelData = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 

[self buildMapWithData:levelData]; 
} 



-(void)buildMapWithData:(NSMutableArray *)lData 
{ 

for(NSDictionary *blueprint in lData){ 

    brickSprite *brick = [[brickSprite alloc] initWithBlueprint:blueprint spriteSheet:@"blocks.png"]; 
    [spriteHolder addChild:brick]; 
} 

} 

Désolé pour le bazar d'une question. Il se passe beaucoup de choses que j'ai du mal à me comprendre pleinement, alors il est difficile de le réduire au strict minimum.

Répondre

3

Vous devez toujours comparer les chaînes avec [firstString isEqualToString:secondString], car firstString == secondString ne vérifie que l'égalité du pointeur, par ex. si les deux chaînes sont stockées au même emplacement (ce qu'elles ne seront jamais en comparant les objets créés dynamiquement et les constantes de chaîne).

+0

si simple. J'essaie d'arrêter de fumer en ce moment, et celui-ci m'a presque remis sur les onglets. Vous êtes littéralement un épargnant de vie. – gargantuan