使用密钥存档/取消归档父子对象

时间:2017-03-17 05:16:18

标签: objective-c nskeyedarchiver

我有一个班级A和一个子类B

@interface A:NSObject<NSCoding>
String a;
String b;
@end
@interface B: A<NSCoding>
int c;
// `a` and `b` attributes are inherited
@end;

我想使用属性AB和部分a的对象归档为key。 这两个类中的encodingdecoding协议已定义为:

@implementation A
...
- (void) encodeWithCoder:(NSCoder *)encoder {
    //[super encodeWithCoder:encoder];
    [encoder encodeObject:self forKey:a];
}

- (id)initWithCoder:(NSCoder *)decoder {
    // self = [super initWithCoder:decoder];
    if (self=[super init]) {
        self = [decoder decodeObjectForKey:a];
    }
    return self;
}
@end

@implementation B
..
 - (void) encodeWithCoder:(NSCoder *)encoder {
    [super encodeWithCoder:encoder];
    [encoder encodeObject:self forKey:super.a];
}

- (id)initWithCoder:(NSCoder *)decoder {
    //self = [super initWithCoder:decoder];
    if (self) {
        self = [decoder decodeObjectForKey:super.a];
    }
    return self;
}

对于某些对象列表dataArray = [A("One"), B("Two")],归档逻辑是

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dataArray];
            NSError* error = nil;
            BOOL success = [data writeToFile: @"xyz.dat" options:0 error: &error];
            if (!success)
                NSLog( @"error = %@", [error description] );

再次阅读存档数据:

NSData *lD = [[NSData alloc] initWithContentsOfFile:@"xyz.dat"];
NSKeyedUnarchiver *arc = [[NSKeyedUnarchiver alloc] initForReadingWithData:lD];

现在,对于属性a"One"的对象 在尝试从存档数据中读取对象时,我收到了null

 NSLog(@"Value - %@",[arc decodeObjectForKey:@"One"]);

1 个答案:

答案 0 :(得分:0)

也许,问题在于编码self。 我做了以下更改:

@implementation A
...
- (void) encodeWithCoder:(NSCoder *)encoder {
    if(self.a!=nil)
        [encoder encodeObject:self.a forKey:@"a"];
    if(self.b!=nil)
        [encoder encodeObject:self.b forKey:@"b"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    self=[super init];
    if (self!=nil) {
        self.a= [decoder decodeObjectForKey:@"a"];
        self.b= [decoder decodeObjectForKey:@"b"]; 
    }
    return self;
}
@end

@implementation B
..
 - (void) encodeWithCoder:(NSCoder *)encoder {
     [super encodeWithCoder:encoder ];
     [encoder encodeObject:self.c forKey:@"c"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if ( (self = [super initWithCoder:decoder ]) )
    {
        self.c= [decoder decodeObjectForKey:@"c"];
    }
    return self;
}

编码数据时:

NSMutableDictionary *dict = [NSMutableDictionary new]; 
[dict setObject:[[A alloc]init()] forKey:@"One"];//say
[dict setObject:[[B alloc]init()] forKey:@"Two"];//say

NSMutableData *yourData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:yourData];
for (NSString* key in dict) {
    id value = [dict objectForKey:key];
    [archiver encodeObject:value forKey: key];
}
[ archiver finishEncoding];
[yourData writeToFile:@"xyz.dat" atomically:YES];
[yourData release];
[archiver release]; 

解码:

NSData *data = [[NSData alloc] initWithContentsOfFile:@"xyz.dat"];
NSKeyedUnarchiver *keyArc= [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSLog(@"%@",[keyArc decodeObjectForKey:@"One"]);
NSLog(@"%@",[keyArc decodeObjectForKey:@"Two"]);
[keyArc finishDecoding];

参考:https://stackoverflow.com/a/10929284/2301570