2013-02-25 58 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]); 

一旦你得到一個錯誤,我們可以從那裏。