【问题标题】:NSKeyedUnarchiver unarchiveObjectWithFile: returns nil in init: methodNSKeyedUnarchiver unarchiveObjectWithFile: 在 init: 方法中返回 nil
【发布时间】:2017-03-14 23:35:07
【问题描述】:

更新:如果我从 applicationDidFinishLaunching: 调用 archiveRootObject: 则有效。如果我从单例类的 init: 方法调用它,它会返回 nil。

我对 NSKeyedUnarchiver unarchiveObjectWithFile: 的行为感到非常困惑。 The documentation 表示如果文件不存在,它将返回 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

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

【问题讨论】:

  • 我怀疑这会解决你的问题,但在 Objective-C 中,正确的术语是 BOOL 而不是 bool
  • 感谢您的提示。这是我的第一个 Objective-C 项目。我已将所有布尔值更新为布尔值。
  • 在 objc_exception_throw 处设置断点,看看是否引发了异常。
  • @Algorithmic 你找到解决方案了吗?

标签: iphone cocoa-touch


【解决方案1】:

我在支持 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!!!

这似乎是 cocoa-touch 的一个错误。

编辑:

它的行为是这样的,而不是一个错误。但我同意命名容易导致错误。

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

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

NSKeyedUnarchiver *coder = [[self alloc] initForReadingWithData:arg2];
id object = [coder decodeObjectForKey:@"root"];

【讨论】:

  • Mac 上也有同样的问题。非常感谢!
【解决方案2】:
  1. 您必须始终 -retain 未归档的对象:Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多