继承NSMutableDictionary并使用NSKeyedArchiver序列化的自定义对象无法反序列化
问题描述:
类未正确解除存档。 请参阅下面的代码示例。继承NSMutableDictionary并使用NSKeyedArchiver序列化的自定义对象无法反序列化
@interface A : NSMutableDictionary
@end
@implementation A
- (void)encodeWithCoder:(NSCoder *)aCoder
{
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
}
return self;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
A *a = [[A alloc] init];
NSMutableDictionary *dict = [NSMutableDictionary new];
dict[@"some"] = a;
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:dict];
dict = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
NSLog(@"%@",dict);
}
unarchiveObjectWithData调用后,将字典中包含一对键@“一些”,但目的是的NSMutableDictionary不是一类。虽然unarchiveObjectWithData调用没有发生initWithCoder调用。 那么,如何让它的代码工作?为什么类继承NSMutableDictionary没有反序列化?
答
这种方法:
- (void)encodeWithCoder:(NSCoder *)aCoder
{
}
包含了对目标的指令编码本身,这是说,“什么也不做”。什么应该说的是:
- (void)encodeWithCoder:(NSCoder *)aCoder
{
// perform the inherited behavior or encoding myself
[super encodeWithCoder:encoder];
}
再次编辑,这个测试类中最微不足道的方法子类的NSMutableDictionary
:通过隐藏一个可变的字典比如在它的实现,并提供原始的方法(PLUS encodeWithCoder
)
#import "MyDict.h"
@interface MyDict()
@property(strong) NSMutableDictionary *internalDictionary;
@end
@implementation MyDict
// changed to the default init for the "new" constructor
- (id)init {
self = [super init];
if (self) {
_internalDictionary = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSUInteger)count {
return [self.internalDictionary count];
}
- (id)objectForKey:(id)aKey {
return [self.internalDictionary objectForKey:aKey];
}
- (void)setObject:(id)anObject forKey:(id<NSCopying>)aKey {
return [self.internalDictionary setObject:anObject forKey:aKey];
}
- (void)removeObjectForKey:(id)aKey {
return [self.internalDictionary removeObjectForKey:aKey];
}
- (NSEnumerator *)keyEnumerator {
return [self.internalDictionary keyEnumerator];
}
// added encoding of the internal representation
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_internalDictionary forKey:@"internalDictionary"];
}
// added decoding of the internal representation
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
_internalDictionary = [aDecoder decodeObjectForKey:@"internalDictionary"];
}
return self;
}
- (Class)classForCoder {
return self.class;
}
@end
再次编辑,这次正好测试:
MyDict *a = [MyDict new];
a[@"hi"] = @"there";
NSMutableDictionary *dict = [NSMutableDictionary new];
dict[@"some"] = a;
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:dict];
dict = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
NSLog(@"%@", dict);
个
日志...
{ 一些= { HI =有; }; }
对不起,但它不起作用。首先,你有没有检查过这个? 我确实尝试过并且崩溃了。 –
什么是崩溃说?你有没有实现所有的NSMutableDictionary原始方法?并且记住,您还必须实现所有不可变的字典原语方法。 – danh
@SashaSewerow - 显示正确性的附加代码。 – danh