views:

192

answers:

1

I'm saving some data using a series of NSDictionaries, stored in an NSMutableArray and archived using NSKeyedArchiver.

I'm basically trying to save the states of several instances the class 'Brick', so I've implemented a getBlueprint method like this (slimmed down version)

-(id)getBlueprint
{

    // NOTE: brickColor is a string

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

}

And so I have another method that creates a new Brick instance when provided with a 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;

    }

Which works when I pass it a 'fresh' blueprint, but not when I read a blueprint from a saved file... sort of. For example, the rotation will work, but changing the color wont. So while I can read the value of brickColor using

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

if I try something like

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

And I know that color is purple, the condition doesn't return true. I thought it might be that somehow NSKeyedUnarchiver changed a string into something else, but the following test returns true.

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

As I said, this isn't a problem if I try to use a freshly created NSDictionary as a blueprint, only when a blueprint is archived and then read back in.

So, as usual, I'm wondering if anyone has any ideas why this might be happening.

incase it's relevant, here's how the data is being stored and recieved.

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

}

Sorry about the mess of a question. There's a lot going on that I'm struggling to fully understand myself so it's hard to break it down to the bare minimum.

+3  A: 

You should always compare strings with [firstString isEqualToString:secondString], because firstString == secondString only checks for pointer equality, e.g. if both strings are stored at the same location (which they'll never be when comparing dynamically created objects and string constants).

MrMage
so simple. I'm trying to quit smoking right now, and this one almost had me back on the tabs. You are literally a life saver.
gargantaun