取消归档使用encodeRootObject归档的内容的正确方法是什么?

时间:2011-05-09 04:41:59

标签: objective-c nscoder

我第一次尝试使用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.");
}

我已经确认归档器正在归档,我假设在归档中存在问题。 根据{{​​3}},我相信也许我使用Unarchiver的方式存在一些问题?

谢谢!

2 个答案:

答案 0 :(得分:1)

首先,您不应使用encodeRootObject方法。这是NSCoder中定义的遗留方法,用于支持过时的非键控归档,并且只能使用decodeObject:进行解码。您只能使用encodeObjectForKey:decodeObjectForKey:对。

所以,

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

应该是

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

如果要解码字典的整体,而不是

[ba encodeRootObject:dict];

DO

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

顺便说一句,出于简单的目的,使用NSUserDefaults通常就足够了,NSKeyedArchiver自动负责创建要写入的文件,在文件上写东西,并在下次启动程序时读取它

如果您只需要编码字典,使用NSPropertyListSerialization通常就足够了。

如果您使用NSKeyedUnarchiverencodeWithCoder:,我建议您按照惯例操作,并为对象写下initWithCoder:和{{1}}。

答案 1 :(得分:0)

    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);
    }