Архивация/разархивация результатов в непонятном архиве initForReadingWithData
-
19-09-2019 - |
Вопрос
Я реализовал сохранение на 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+ МБ
- (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."
Решение 2
Кажется, что сохранение более 230 000 байт через NSMutableArray приведет к тому, что NSKeyedArchiver создаст испорченный файл plist.
220000 работает, 250000 нет.Искал точную сумму, которая разрешена.
Другие советы
Кстати, я тоже столкнулся с этой проблемой и вот что нашел.
Байты, о которых сообщают 0x62, 0x70, 0x6c и т. д., являются частью магической строки «bplist» в начале списка двоичных свойств, который NSKeyedArchiver использует по умолчанию.
Список двоичных свойств хранит метаданные в трейлере (т. е.в конце данных).Поэтому, если он будет усечен, весь список станет нечитаемым.
Если вы хотите проверить, случилось ли это с вами, вы можете использовать NSPropertyListReader_binary1 от Cocotron (http://code.google.com/p/cocotron/source/browse/Foundation/NSPropertyList/), чтобы увидеть, как работает формат файла.
Надеюсь, это кому-то поможет!
Для bool и int существует два метода: encodeBool:forKey:
и encodeInt:forKey:
(взято из Справочник по NSKeyedArchiver).
Что касается NSmutableData, вам следует заархивировать их с помощью encodeObjectForKey:
и разархивировать их с помощью decodeObjectForKey:
.
Вы можете обратиться к этому полезное руководство для большего количества случаев.