Archiving / Unarchiving causes initForReadingWithData an incomprehensible archive

I implemented persistence on applicationWillTerminate and loaded on applicationWillFinishLoading . There is a complete tree of objects, all implement the NSCoding protocol, and I check the types that I entered.

One of the classes also stores NSMutableData in NSKeyedArchive , which, I suspect, can sometimes be interrupted. Oddly enough, sometimes it works, and sometimes not. I suspect some content in NSMutableData will violate archiving.

I use encodeObject for all objects except bools and int, where I use the correct appropriate method ( encodeBool:forKey: and encodeInt:forKey:

To be more clear: the code really works, sometimes it is able to rebuild a fairly complete graph of objects, but not all the time.

The error message I get is:

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

Added: code that does not work is NSMutableData from 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; } 

When I delete self.data encoding and decoding, it always works. It also fails with a smaller self.data size. Unlike size, but content issue?

I tried to open the file, when I wrote nsmutabledata to it, the correct list editor displays an error:

 "Conversion of string failed. The string is empty." 

plutil also gives this error:

 "$ plutil -lint nzbvortex.state nzbvortex.state: Conversion of string failed. The string is empty." 
+4
source share
3 answers

It seems that storing over 230,000 bytes via NSMutableArray will force NSKeyedArchiver to create a broken plist file.

220,000 works, 250,000 no. There was a search for the exact amount that is allowed.

+2
source

FWIW I also ran into this problem and this is what I found.

Described bytes 0x62, 0x70, 0x6c, etc. are part of the bplist magic line at the top of the binary property list, which NSKeyedArchiver uses by default.

The binary property list stores metadata in the trailer (i.e. at the end of the data). Therefore, if it is truncated, the entire layer becomes unreadable.

If you want to check what happened to you, you can use NSPropertyListReader_binary1 from Cocotron ( http://code.google.com/p/cocotron/source/browse/Foundation/NSPropertyList/ ) to see how the file format works.

Hope this helps someone!

+4
source

There are two methods for bool and int: encodeBool:forKey: and encodeInt:forKey: (taken from the NSKeyedArchiver link ).

For NSMutableData, you must archive them using encodeObjectForKey: and unlock them with decodeObjectForKey:

You can refer to this helpful guide for other occasions.

0
source

All Articles