在我的iOS应用程序中,我正在对Entity进行大量迁移,我将旧数据模型中Integer64的属性类型转换为新数据模型中的String类型。此属性的转换似乎正常。但是,我遇到的问题是同一个Entity的另一个属性是null(这应该是它应该是什么),当这个属性被迁移到新模式中的同一个实体时,会标记一个错误:
*** 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;
}
任何人都可以看到它的错误吗?
答案 0 :(得分: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
。