从NSDictionary迁移到Object的最佳方法

时间:2016-11-18 01:40:04

标签: cocoa nsdictionary nscoding

我有一个符合NSCoding的对象(并存档到磁盘)。该对象的一个​​属性(myMetrics)是NSDictionary。在该软件的新版本中,我需要为此词典添加一个键,但我需要在应用程序的其余部分使用主对象之前执行此操作,因为它是必需的键。

我的想法是做一些事情:

-(id)initWithCoder:(NSCoder *)coder
{
    if (self = [super init])
    {
       self.myMetrics = [coder decodeObjectForKey:@"myMetrics"];
       ... other properties go here ....
    }

    .... add the new key to myMetrics with default value if it is missing in myMetrics ...

    return (self);
}

我真正想做的是将myMetrics从字典转换为它自己的类。我不确定如何处理已存在的已归档对象。我的想法是:

  1. 添加NewMetrics类的新属性newMetrics。
  2. 如果找到myMetrics属性,则在initWithCoder中
  3. ,将其数据移动到newMetrics属性
  4. 在encodeWithCoder中,
  5. 只处理newMetrics,永远不会重新编码旧字典。
  6. 通过这种方式,软件始终使用NewMetrics对象,但initWithCoder能够处理旧样式myMetrics。

    在保留相同的属性名称时有没有什么好方法可以做到?

    @property (atomic, retain) NSDictionary* myMetrics; //  dictionary of parameters
    
    becomes
    
    @property (atomic, retain) NewMetrics* myMetrics; // parameters
    
    rather than
    
    @property (atomic, retain) NewMetrics* newMetrics; // parameters
    

    有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

是的,您可以将myMetrics从字典转换为自己的类,而无需重命名属性,同时仍处理现有的归档对象。新的财产声明将是:

@property (atomic, retain) NewMetrics* myMetrics; // parameters

initWithCoder:函数类似于:

-(id)initWithCoder:(NSCoder *)coder
{
    if (self = [super init])
    {
        // decode saved NewMetrics object
        self.myMetrics = [coder decodeObjectForKey:@"newMyMetrics"];
        if (!self.myMetrics) {
            // fall back to legacy saved metrics NSDictionary
            NSDictionary *legacyMetrics = [coder decodeObjectForKey:@"myMetrics"];
            if (legacyMetrics) {
                self.myMetrics = [[NewMetrics alloc] initWithDictionary:legacyMetrics];
            } else {
                // handle having no saved metrics
            }
        }

        ... other properties go here ....
    }

    return self;
}

您必须在新密钥下开始编码myMetrics属性,例如@"myNewMetrics",并提供一种将旧式度量字典转换为新NewMetrics类的实例的方法,例如: initWithDictionary:,如上所示。