NSKeyedUnarchiver unarchiveObjectWithFile:在init:方法中返回nil

bra*_*onb 9 iphone cocoa-touch

更新:如果我从applicationDidFinishLaunching中调用archiveRootObject:如果我从singleton类的init:方法调用它,它返回nil.

我对NSKeyedUnarchiver unarchiveObjectWithFile的行为非常困惑.文档说如果文件不存在,它将返回nil.使用我的一个对象,会发生以下情况:

Game *g1 = [Game getGame];
NSString *archivePath = [Game getArchivePath];
bool success = [NSKeyedArchiver archiveRootObject:g1 toFile:archivePath];
Game *g2 = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];

// success is true, g2 is nil
Run Code Online (Sandbox Code Playgroud)

我已经验证该文件确实存在并且正由archiveRootObject:方法写入.我做错了什么阻止我将游戏对象从存档中取回?

poG*_*Ist 8

我在ARC支持的Xcode 4.1中遇到了同样的问题:

BOOL isFileExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
NSAssert(isFileExist, @"filePath does not exist");
NSKeyedUnarchiver* coder =
    [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; // nil
NSData* data = [[NSFileManager defaultManager] contentsAtPath:filePath];
coder = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // nil
coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; // OK!!!
Run Code Online (Sandbox Code Playgroud)

它似乎是可可触摸中的一个错误.

编辑:

它的行为与此类似,并不是一个错误.但我同意命名很容易导致错误.

[[NSKeyedUnarchiver alloc] initForReadingWithData:]返回一个NSKeyedUnarchiver实例.

[NSKeyedUnarchiver unarchiveObjectWithData:]返回根对象.这是一种方便的方法:

NSKeyedUnarchiver *coder = [[self alloc] initForReadingWithData:arg2];
id object = [coder decodeObjectForKey:@"root"];
Run Code Online (Sandbox Code Playgroud)


SK9*_*SK9 2

  1. 您必须始终-retain是未归档的对象:Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

  2. 你的g2符合吗NSCoding?如果未<NSCoding>g2标头中声明,请确保它已声明。在实现文件中定义方法-(id)initWithCoder:(NSCoder *)coder-(void)encodeWithCoder:(NSCoder *)coder

  3. 如果您正在努力使其正常工作,请考虑归档和取消归档标准 NSObject,例如 NSString 或类似的东西。您可能不需要存档整个自定义对象,可能只是剩余时间数、游戏位置或位置或得分。换句话说,归档和取消归档您需要的最低限度。