使用密钥归档/取消归档父子对象
Posted
技术标签:
【中文标题】使用密钥归档/取消归档父子对象【英文标题】:Archive/Unarchive Parent-Child objects with a key 【发布时间】:2017-03-17 05:16:18 【问题描述】:我有一个类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
。
两个类中的encoding
和decoding
协议都被定义为:
@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"]);
【问题讨论】:
查看此链接***.com/questions/41116832/… 【参考方案1】:也许,问题在于编码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://***.com/a/10929284/2301570
【讨论】:
以上是关于使用密钥归档/取消归档父子对象的主要内容,如果未能解决你的问题,请参考以下文章
NSKeyedUnarchiver.unarchiveObject() 取消归档旧对象
如何在 Swift 中归档和取消归档自定义对象?或者如何在 Swift 中将自定义对象保存到 NSUserDefaults?
在 Swift 中的 DocumentDirectory 中归档和取消归档数组
故事板错误取消归档文档对象 - *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil