【问题标题】:Problem reading a string from an NSDictionary inside an NSMutableArray stored using NSKeyedArchiver从使用 NSKeyedArchiver 存储的 NSMutableArray 中的 NSDictionary 读取字符串时出现问题
【发布时间】:2010-12-20 09:19:23
【问题描述】:

我正在使用一系列 NSDictionaries 保存一些数据,这些数据存储在 NSMutableArray 中并使用 NSKeyedArchiver 存档。

我基本上是在尝试将几个实例的状态保存为“Brick”类,所以我实现了一个像这样的 getBlueprint 方法(精简版)

-(id)getBlueprint
{

    // NOTE: brickColor is a string

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

}

所以我有另一种方法,可以在提供蓝图时创建一个新的 Brick 实例。

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

    }

当我将“新”蓝图传递给它时,它会起作用,但当我从保存的文件中读取蓝图时则不起作用......有点。例如,旋转会起作用,但改变颜色不会。因此,虽然我可以使用

读取brickColor 的值
NSLog(@"brick color %@", [blueprint objectForKey:@"color"]);

如果我尝试类似

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

而且我知道颜色是紫色,条件不返回 true。我认为可能是 NSKeyedUnarchiver 以某种方式将字符串更改为其他内容,但以下测试返回 true。

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

正如我所说,如果我尝试使用新创建的 NSDictionary 作为蓝图,这不是问题,只有当蓝图被存档然后重新读入时。

所以,像往常一样,我想知道是否有人知道为什么会发生这种情况。

如果相关,以下是数据的存储和接收方式。

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

}

抱歉,问题一团糟。发生了很多事情,我正在努力完全了解自己,因此很难将其分解到最低限度。

【问题讨论】:

    标签: iphone cocoa-touch nsmutablearray nsdictionary nskeyedarchiver


    【解决方案1】:

    您应该始终将字符串与[firstString isEqualToString:secondString] 进行比较,因为firstString == secondString 只检查指针是否相等,例如如果两个字符串都存储在同一位置(在比较动态创建的对象和字符串常量时它们永远不会存在)。

    【讨论】:

    • 如此简单。我现在正在尝试戒烟,而这一次几乎让我回到了标签上。你真的是一个救生员。
    猜你喜欢
    • 2013-06-09
    • 2023-03-24
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    相关资源
    最近更新 更多