继承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 =有; }; }

+0

对不起,但它不起作用。首先,你有没有检查过这个? 我确实尝试过并且崩溃了。 –

+0

什么是崩溃说?你有没有实现所有的NSMutableDictionary原始方法?并且记住,您还必须实现所有不可变的字典原语方法。 – danh

+0

@SashaSewerow - 显示正确性的附加代码。 – danh