Objective c 存档/取消存档会导致initforreading中的数据不可理解的存档

Objective c 存档/取消存档会导致initforreading中的数据不可理解的存档,objective-c,xcode,macos,archiving,nscoding,Objective C,Xcode,Macos,Archiving,Nscoding,我已经在applicationWillTerminate上实现了保存,并在applicationwillfinishload上实现了加载。 有一个完整的对象树,它们都实现了NSCoding协议,我已经检查了输入的类型 其中一个类还将一个NSMutableData存储到NSKeyedArchive中,我怀疑它可能偶尔会破坏unarchiving。奇怪的是,有时有效,有时无效。我怀疑NSMutableData中的某些内容会破坏归档 我在所有对象上使用encodeObject,除了bools和int之

我已经在
applicationWillTerminate
上实现了保存,并在
applicationwillfinishload
上实现了加载。 有一个完整的对象树,它们都实现了
NSCoding
协议,我已经检查了输入的类型

其中一个类还将一个
NSMutableData
存储到
NSKeyedArchive
中,我怀疑它可能偶尔会破坏unarchiving。奇怪的是,有时有效,有时无效。我怀疑
NSMutableData
中的某些内容会破坏归档

我在所有对象上使用encodeObject,除了bools和int之外,在bools和int中我使用了正确的对应方法(
encodeBool:forKey:
encodeInt:forKey:

更清楚地说:代码确实有效,有时它能够重建一个相当完整的对象图,只是不是一直都能

我收到的错误消息是:

initForReadingWithData incomprehensible archive 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30
添加:失败的代码,它是一个10+MB的
NSMutableData

- (void)encodeWithCoder:(NSCoder*)encoder {
[encoder encodeObject:self.encodedMessage forKey:@"EncodedMessage"]; //NSData
[encoder encodeObject:self.data forKey:@"Data"]; //NSMutableData (10+MB)
[encoder encodeObject:self.header forKey:@"Header"]; //NSString
[encoder encodeObject:self.fileName forKey:@"FileName"]; //NSString
[encoder encodeInt:self.dataStartIndex forKey:@"DataStartIndex"]; //int
[encoder encodeInt:self.dataEndIndex forKey:@"DataEndIndex"]; //int
}

- (id)initWithCoder:(NSCoder*)decoder {
    if (self = [super init]) {
        self.encodedMessage = [decoder decodeObjectForKey:@"EncodedMessage"]; //NSData
        self.data = [decoder decodeObjectForKey:@"Data"]; //NSMutableData
        self.header = [decoder decodeObjectForKey:@"Header"]; //NSString
        self.fileName = [decoder decodeObjectForKey:@"FileName"]; //NSString
        self.dataStartIndex = [decoder decodeIntForKey:@"DataStartIndex"]; //int
        self.dataEndIndex = [decoder decodeIntForKey:@"DataEndIndex"]; //int
    }

    return self;
}
当我删除self.data编码和解码时,它似乎总是起作用。 对于较小大小的self.data,它也会失败。似乎不是大小而是内容问题

当我将nsmutabledata写入文件时,试图打开该文件,属性列表编辑器显示错误:

"Conversion of string failed. The string is empty."
plutil也给出了这个错误:

"$ plutil -lint nzbvortex.state nzbvortex.state: Conversion of string failed. The string is empty."

对于bool和int,有两种方法:
encodeBool:forKey:
encodeInt:forKey:
(取自)

对于NSMutableData,应使用
encodeObjectForKey:
对其进行归档,并使用
decodeObjectForKey:
取消归档


更多情况下,您可以参考这一点。

似乎通过NSMutableArray存储超过230000字节会导致NSKeyedArchiver创建一个损坏的plist文件


22万件作品,25万件没有。确实搜索了允许的确切数量。

FWIW我也遇到了这个问题,以下是我的发现

报告的字节0x62、0x70、0x6c等是二进制属性列表开头的神奇字符串“bplist”的一部分,NSKeyedArchiver默认使用该字符串

二进制属性列表将元数据存储在尾部(即数据末尾)。因此,如果它被截断,整个plist将无法读取

如果要检查是否发生了这种情况,可以使用Cocotron()中的NSPropertyListReader_binary1查看文件格式的工作方式


希望这对别人有帮助

这正是我所做的。代码可以工作,但并不总是如此。看起来特定内容似乎破坏了编码。您使用的是XML属性列表格式吗?如果是这样,您是否尝试过使用PList编辑器(在开发工具中)打开存档?使用NSKeyedArchiver时,nsmutabledata中存储的字节数似乎有限制。问题已解决(实际上已绕过)。谢谢你的帮助。对我来说,确切的错误是数据被破坏了,就像你说的。你的答案应该是对的。谢谢。这是因为正在构造二进制plist。我也遇到了这个问题。错误信息与您的完全相同。我在
NSFileCoordinator
读取块中使用
nskeyedurchiver
读取另一个线程中由
nskeyedurchiver
存档的非归档数据。崩溃偶尔会发生,调试时我无法再现它。你有解决办法吗?