使用键存档/取消存档父子对象



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

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

我想使用属性a存档一些A对象和一些B对象作为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"]);
也许

,问题出在编码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

最新更新