在 Core Data 中进行重量级迁移时尝试迁移 nil 属性值
Posted
技术标签:
【中文标题】在 Core Data 中进行重量级迁移时尝试迁移 nil 属性值【英文标题】:Trying to migrate nil attribute value when doing heavy weight migration in Core Data 【发布时间】:2014-03-10 20:23:19 【问题描述】:在我的 ios 应用程序中,我正在对实体进行重量级迁移,其中我将属性的类型从旧数据模型中的 Integer64 转换为新数据模型中的 String 类型。此属性的转换似乎工作正常。但是,我遇到的问题是同一个实体的另一个属性为空(它应该是),当这个属性被迁移到新模式中的同一个实体时,一个错误被标记:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "date"; desired type = NSDate; given type = NSNull; value = <null>.'
我不确定为什么要标记此错误,因为该属性在数据模型中被标记为可选。我想简单地将属性的 nil 值“按原样”迁移到新数据模型中的相同属性,而不进行任何更改或修改。
这是我正在使用的 NSEntityMigrationPolicy 子类的相关代码:
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError *__autoreleasing *)error
NSManagedObject *newObject;
NSEntityDescription *sourceInstanceEntity = [sInstance entity];
//correct entity? just to be sure
if ([[sourceInstanceEntity name] isEqualToString:@"MyEntity"])
newObject = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:[manager destinationContext]];
//obtain the attributes
NSDictionary *keyValDict = [sInstance committedValuesForKeys:nil];
NSArray *allKeys = [[[sInstance entity] attributesByName] allKeys];
//loop over the attributes
for (NSString *key in allKeys)
//get key and value
id value = [keyValDict objectForKey:key];
if ([key isEqualToString:@"integerType"])
//here retrieve old value
NSNumber *oldValue = [keyValDict objectForKey:key];
//here do conversion as needed
NSString *stringType = [oldValue stringValue];
//then store new value
[newObject setValue:stringType forKey:key];
else //no need to modify the value, Copy it across -- this is where I believe the problem is
[newObject setValue:value forKey:key];
[manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
return YES;
谁能看出我做错了什么?
【问题讨论】:
【参考方案1】:问题是您在字典中返回了 NSNull
类,这意味着您试图将错误类型的类传递给新的 NSManagedObject
实例。
如果您阅读-committedValuesForKeys:
上的文档,您会看到:
nil
值由NSNull
的实例表示。
这是你的问题。
就我个人而言,我不会以这种方式处理价值观。相反,我会这样做:
NSDictionary *allAttributes = [[sInstance entity] attributesByName];
for (NString *key in allAttributes)
id value = [sInstance valueForKey:key];
if ([key isEqualToString:@"integerType"])
//here retrieve old value
NSNumber *oldValue = [keyValDict objectForKey:key];
//here do conversion as needed
NSString *stringType = [oldValue stringValue];
//then store new value
[newObject setValue:stringType forKey:key];
else //no need to modify the value, Copy it across -- this is where I believe the problem is
[newObject setValue:value forKey:key];
您直接从对象中获取值,您将得到正确的nil
返回。
【讨论】:
非常感谢您的解决方案,它奏效了!如果您有时间,可以看看下一个问题:***.com/questions/22330445/… 吗?再次感谢您的宝贵时间和帮助!以上是关于在 Core Data 中进行重量级迁移时尝试迁移 nil 属性值的主要内容,如果未能解决你的问题,请参考以下文章