Как правильно разархивировать что-то, что было заархивировано с помощью encodeRootObject :? - PullRequest
1 голос
/ 09 мая 2011

Я пытаюсь использовать классы Keyed Archiver впервые и не могу выполнить последнее утверждение в этом простом тесте (OCUnit):

- (void) testNSCoding
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:5];
    [dict setObject:@"hello" forKey:@"testKey"];

    NSMutableData* data = [NSMutableData data];
    NSKeyedArchiver *ba = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [ba encodeRootObject:dict];
    [ba finishEncoding];

    STAssertTrue(data.length != 0, @"Archiver gave us nothing.");

    NSKeyedUnarchiver *bua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    id decodedEntity = [bua decodeObjectForKey:@"root"];
    [bua finishDecoding];
    STAssertNotNil(decodedEntity, @"Unarchiver gave us nothing.");
}

Я подтвердил, что архиватор архивирует,Я предполагаю, что проблема существует в разархивировании.Согласно Руководству по архивам и сериализации Я считаю, что, возможно, есть какая-то проблема с тем, как я использую Unarchiver?

Спасибо!

Ответы [ 2 ]

1 голос
/ 09 мая 2011

Во-первых, вы не должны использовать метод encodeRootObject. Это устаревший метод, определенный в NSCoder для поддержки устаревших неключевых архиваторов, и может быть декодирован только с использованием decodeObject:. Вы используете только пару encodeObjectForKey: и decodeObjectForKey:.

Итак,

 id decodedEntity = [bua decodeObjectForKey:@"root"];

должно быть

 id decodedEntity = [bua decodeObjectForKey:@"testKey"];

Если вы хотите расшифровать весь словарь, вместо

[ba encodeRootObject:dict];

сделать

[ba encodeObject:dict forKey:@"root"];

Кстати, для простых целей часто достаточно использовать NSUserDefaults, который автоматически заботится о создании файла для записи, записи объектов в файл и чтении его при следующем запуске программы.

Если вам просто нужно закодировать словарь, обычно достаточно использовать NSPropertyListSerialization.

Если вы используете NSKeyedArchiver и NSKeyedUnarchiver, я рекомендую вам следовать практике и написать encodeWithCoder: и initWithCoder: для объекта.

0 голосов
/ 27 мая 2014
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    id profileData = [defaults dataForKey:kProfileDataKey]; // or you can get it from the web
    if (profileData && [profileData isKindOfClass:[NSData class]]) {
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)profileData];
        unarchiver.requiresSecureCoding = YES; // <NSSecureCoding>
        id object = [unarchiver decodeObjectOfClass:[MyClass class] forKey:NSKeyedArchiveRootObjectKey];
        NSLog(@"%@", object);
    }
...