在Core Data中进行重量级迁移时尝试迁移nil属性值

时间:2014-03-10 20:23:20

标签: ios core-data

在我的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;
}

任何人都可以看到它的错误吗?

1 个答案:

答案 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