从 NSDictionary 迁移到 Object 的最佳方式
Best way to migrate from NSDictionary to Object
我有一个符合 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 从字典转换为它自己的 class。我不确定我将如何处理已经存在的归档对象。我的想法是:
- 添加一个名为 newMetrics 的新 属性 class NewMetrics。
- 在 initWithCoder 中如果找到 myMetrics 属性,将其数据移动到 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
从字典转换为它自己的 class,而无需重命名 属性,同时仍处理现有的存档对象。新的 属性 声明为:
@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 class 实例的方法,例如initWithDictionary:
如上图
我有一个符合 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 从字典转换为它自己的 class。我不确定我将如何处理已经存在的归档对象。我的想法是:
- 添加一个名为 newMetrics 的新 属性 class NewMetrics。
- 在 initWithCoder 中如果找到 myMetrics 属性,将其数据移动到 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
从字典转换为它自己的 class,而无需重命名 属性,同时仍处理现有的存档对象。新的 属性 声明为:
@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 class 实例的方法,例如initWithDictionary:
如上图