Архивирование / Разархивирование результатов в непонятном архиве initForReadingWithData - PullRequest
4 голосов
/ 08 января 2010

Я реализовал сохранение на 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."

Ответы [ 3 ]

4 голосов
/ 10 апреля 2013

FWIW Я также сталкивался с этой проблемой, и вот что я нашел.

Байты, сообщенные 0x62, 0x70, 0x6c и т. Д., Являются частью магической строки "bplist" в началесписка двоичных свойств, который по умолчанию использует NSKeyedArchiver.

Список двоичных свойств хранит метаданные в трейлере (т.е. в конце данных).Поэтому, если он усекается, весь plist становится нечитабельным.

Если вы хотите проверить, что с вами произошло, вы можете использовать NSPropertyListReader_binary1 из Cocotron (http://code.google.com/p/cocotron/source/browse/Foundation/NSPropertyList/), чтобы увидеть, как формат файлаработает.

Надеюсь, это кому-нибудь поможет!

2 голосов
/ 09 января 2010

Кажется, что хранение более 230000 байт через NSMutableArray приведет к тому, что NSKeyedArchiver создаст поврежденный файл plist.

220000 работ, 250000 - нет. Сделал поиск точной суммы, которая разрешена.

0 голосов
/ 08 января 2010

Для bool и int есть два метода: encodeBool:forKey: и encodeInt:forKey: (взято из ссылки NSKeyedArchiver ).

Для NSMutableData вы должны заархивировать их с помощью encodeObjectForKey: и разархивировать с помощью decodeObjectForKey:.

Вы можете обратиться к этому полезному руководству для большего количества случаев.

...