我有一个符合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从字典转换为它自己的类。我不确定如何处理已经存在的归档对象。我的想法是:


添加名为newMetrics的类NewMetrics的新属性。
如果找到myMetrics属性,请在initWithCoder中将其数据移到newMetrics属性中
在encodeWithCoder中,仅处理newMetrics,而从不对旧字典进行重新编码。


这样,软件将始终使用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


有没有更好的办法?

最佳答案

是的,您可以将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:如上所示。

08-05 06:33