归档/取消归档导致initForReadingWithData难以理解的归档

时间:2010-01-08 09:53:48

标签: objective-c xcode macos archiving nscoding

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

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

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

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

我得到的错误信息是:

initForReadingWithData incomprehensible archive 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30

补充:失败的代码,NSMutableData 10+ MB

- (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."

3 个答案:

答案 0 :(得分:4)

FWIW我也遇到过这个问题,这就是我发现的。

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

二进制属性列表在预告片中(即在数据的末尾)存储元数据。因此,如果它被截断,整个plist变得不可读。

如果您想检查是否发生了这种情况,您可以使用Cocotron的NSPropertyListReader_binary1(http://code.google.com/p/cocotron/source/browse/Foundation/NSPropertyList/)来查看文件格式的工作原理。

希望这有助于某人!

答案 1 :(得分:2)

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

220000作品,25万没作。是否搜索了允许的确切数量。

答案 2 :(得分:0)

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

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

您可以参考此useful guide了解更多案例。