在NSMutableDictionary的派生类中未调用encodeWithCoder [英] encodeWithCoder is not called in derived class of the NSMutableDictionary

查看:52
本文介绍了在NSMutableDictionary的派生类中未调用encodeWithCoder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我正在使用一些称为OrderedDictionary的开源代码,该代码是从NSMutableDictionary派生的.然后,我想通过将编码和解码方法添加到OrderedDictionary类来将有序字典数据保存到NSUserDefaults中.但是,我意识到没有调用编码和解码方法,因此,解码后的字典不再有序.下面是我的代码:

Basically I am using some open source code called OrderedDictionary that is derived from NSMutableDictionary. Then I want to save the ordered dictionary data to NSUserDefaults by adding encode and decode method to the OrderedDictionary class. However, I realized the encode and decode methods are not being called, as a result, the decoded dictionary is no longer ordered. Below is my code:

@interface OrderedDictionary : NSMutableDictionary <NSCopying, NSCoding>
{
    NSMutableDictionary *dictionary;
    NSMutableArray *array;
}

在实施文件中:

/**
 * encode the object
 **/
- (void)encodeWithCoder:(NSCoder *)coder
{
    [super encodeWithCoder:coder];
    [coder encodeObject:dictionary forKey:@"dictionary"];
    [coder encodeObject:array forKey:@"array"];
}

/**
 * decode the object
 */
- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self != nil)
    {
        dictionary = [coder decodeObjectForKey:@"dictionary"];
        array = [coder decodeObjectForKey:@"array"];
    }   
    return self;
}

使用此示例的快速示例代码:

Quick example code for using this:

dictionary = [[OrderedDictionary alloc] init];
[dictionary setObject:@"one" forKey:@"two"];
[dictionary setObject:@"what" forKey:@"what"];
[dictionary setObject:@"7" forKey:@"7"];
NSLog(@"Final contents of the dictionary: %@", dictionary);

if ([[NSUserDefaults standardUserDefaults] objectForKey:@"myDictionary"] == nil)
{
    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:dictionary] 
                                          forKey:@"myDictionary"];
}
else
{
    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];

    NSData *savedDictionary = [currentDefaults objectForKey:@"myDictionary"];

    if (savedDictionary != nil)
    {
        OrderedDictionary *oldData = [NSKeyedUnarchiver unarchiveObjectWithData:savedDictionary];
        if (oldData != nil) 
        {
            NSLog(@"Final contents of the retrieved: %@", oldData);

        } 
    }
}

问题是,最终的retriatedDictionary没有原始数据顺序,并且根本不调用编码和解码方法.

The thing is, the final retrievedDictionary does NOT have the original data order and the encode and decode methods are not called at all.

感谢您的任何帮助!:)

Thanks for any help in advance! :)

推荐答案

有一个名为 -classForCoder 的NSObject方法,您需要在OrderedDictionary中覆盖该方法.从文档中:

There's an NSObject method called -classForCoder that you need to override in OrderedDictionary. From the docs:

classForCoder
在编码过程中被子类覆盖以替代其自身之外的其他类.

classForCoder
Overridden by subclasses to substitute a class other than its own during coding.

-(Class)classForCoder
返回值
在编码过程中代替接收者自己的类的类.

-(Class)classForCoder
Return Value
The class to substitute for the receiver's own class during coding.

讨论
此方法由NSCoder调用.NSObject的实现返回接收方的类.的私有子类在以下情况下,类集群替换其公共超类的名称正在存档.

Discussion
This method is invoked by NSCoder. NSObject’s implementation returns the receiver’s class. The private subclasses of a class cluster substitute the name of their public superclass when being archived.

最后一行是关键.因此,在OrderedDictionary.m中:

That last line is the key. So, in OrderedDictionary.m:

- (Class)classForCoder 
{  
    return [self class]; // Instead of NSMutableDictionary
} 

此外,如果您不使用ARC,请确保保留从 -decodeObjectForKey 返回的对象.正如rob mayoff在下面提到的那样,您不应调用 [super initWithCoder:] (或 [super encodeWithCoder:')".我还更改了键串以避免碰撞.

Also, if you're not using ARC, make sure you retain the objects coming back from -decodeObjectForKey. As rob mayoff mentions below, you shouldn't call [super initWithCoder:] (or [super encodeWithCoder:'). I also changed the key strings to avoid collisions.

- (id)initWithCoder:(NSCoder *)coder
{
    if (self != nil)
    {
        dictionary = [[coder decodeObjectForKey:@"OrderedDictionary_dictionary"] retain];
        array = [[coder decodeObjectForKey:@"OrderedDictionary_array"] retain];
    }   
    return self;
}

这篇关于在NSMutableDictionary的派生类中未调用encodeWithCoder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆