2013-02-25 59 views
0

我已经写以下方法错误的值-iOS编码/解码数据..NSCoding -decoder返回

- (void) encode: (BOOL) encodeBool int: (NSNumber *) integer boolean:(BOOL) boolean key: (NSString *) keyStr { 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:@"gameData"]; 



    if (encodeBool == YES) { 

     NSMutableData *gameData = [NSMutableData data]; 
     NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:gameData]; 

     if (integer) { 
      [encoder encodeInt:[integer intValue] forKey:keyStr]; 
     } 
     else if (boolean) { 
      [encoder encodeBool:boolean forKey:keyStr]; 
     } 

     [encoder finishEncoding]; 
     [gameData writeToFile:gameStatePath atomically:YES]; 
     [encoder release]; 


    } else { 

     NSMutableData *gameData = [NSData dataWithContentsOfFile:gameStatePath]; 

     if (gameData) { 

      NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:gameData]; 

      if (integer) { 
       NSLog(@"%d", [decoder decodeIntForKey:keyStr]); 
      } 
      else if (boolean) { 

       if ([decoder decodeBoolForKey:keyStr]==YES) { 
        NSLog(@"YES"); 

       } else { 
        NSLog(@"NO"); 
       } 

      } 



      [decoder finishDecoding]; 
      [decoder release]; 

     } 


    } 



} 

和一些测试

[[GameData sharedData] encode:YES int: [NSNumber numberWithInt:100] boolean:NO key:@"testInt"]; 
    [[GameData sharedData] encode:YES int:nil boolean:YES key:@"bool"];   
    [[GameData sharedData] encode:YES int:[NSNumber numberWithInt:1030] boolean:nil key:@"test"]; 

    [[GameData sharedData] encode:NO int: [NSNumber numberWithInt:1] boolean:nil key:@"testInt"]; 
    [[GameData sharedData] encode:NO int:nil boolean:YES key:@"bool"]; 
    [[GameData sharedData] encode:NO int:[NSNumber numberWithInt:100] boolean:nil key:@"test"]; 

和输出是

0 
NO 
1030 

只有最后一个是正确的..有人可以告诉我我做错了什么?谢谢

回答

2

你的问题是,每次你调用你的方法时,你都会覆盖文件 - 擦除你在以前的调用中编码的值。您应该重写您的方法,以便在一次调用中对所有值进行编码。

一个替代方案是创建一个GameState对象,并把它落实NSCoding,然后阅读并+[NSKeyedArchiver archiveRootObject:toFile:]序列化与反序列化+[NSKeyedUnarchiver unarchiveObjectWithFile:]它。代码如下:

@interface GameState : NSObject <NSCoding> 

@property (nonatomic) int someInt; 
@property (nonatomic) BOOL someBool; 
@property (nonatomic, strong) NSString *someString; 

@end 

static NSString *const BoolKey = @"BoolKey"; 
static NSString *const StringKey = @"StringKey"; 
static NSString *const IntKey = @"IntKey"; 

@implementation GameState 

- (id)initWithCoder:(NSCoder *)coder 
{ 
    self = [super init]; 
    if (self) { 
     _someBool = [coder decodeBoolForKey:BoolKey]; 
     _someInt = [coder decodeIntForKey:IntKey]; 
     _someString = [coder decodeObjectForKey:StringKey]; 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)aCoder 
{ 
    [aCoder encodeBool:self.someBool forKey:BoolKey]; 
    [aCoder encodeInt:self.someInt forKey:IntKey]; 
    [aCoder encodeObject:self.someString forKey:StringKey]; 
} 

@end 

// Somewhere in your app where reading and saving game state is needed... 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = nil; 
if ([paths count]) { 
    documentsDirectory = paths[0]; 
} 
NSString *archivePath = [documentsDirectory stringByAppendingPathComponent:@"archive"]; 
GameState *gameState = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath]; 
if (!gameState) { 
    gameState = [[GameState alloc] init]; 
    gameState.someString = @"a string"; 
    gameState.someInt = 42; 
    gameState.someBool = YES; 
} 

// Make changes to gameState here... 

[NSKeyedArchiver archiveRootObject:gameState toFile:archivePath]; 
2

第一个问题是,当你测试if (boolean)它就像说if (boolean == YES)一样。 Bools不是物体,不能是nil。当你通过nil作为bool时,它与通过NO英寸相同。我不认为这会解释所有问题。我认为这个文件并没有保存。

从NSKeyedUnarchiver文档:

如果调用解码的一个...使用密钥 不会在归档中存在这个类的方法,则返回一个非正值。 该值因解码类型而异。例如,如果档案中存在密钥 ,decodeBoolForKey:返回NO,decodeIntForKey: 返回0,decodeObjectForKey:返回nil。

这些是你得到的错误值。首先,我注意到你没有进行错误检查。尝试添加一些检查,看看是怎么失败的,例如,你可以尝试:

[encoder finishEncoding]; 
    NSError *error; 
    BOOL success = [gameData writeToFile:gameStatePath options:NSDataWritingAtomic error:&error]; 
    if (success == NO) NSLog(@"Error: %@", [error localizedDescription]); 

一旦你得到一个错误,我们可以从那里。