0

我正在使用带有一些复杂数据模型的 Core Data。有很多地方将取消设置字符串属性,并且nil在检索属性时显然在这些情况下 Core Data 会返回。我想通常覆盖此行为,以便如果数据模型的任何字符串属性返回 nil ,它将返回一个空字符串。

在 Core Data 之上,我同时使用了 mogenerator 和 Magical Record。我的数据模型中的所有实体都直接或间接继承自 AbstractEntity,所以我希望我可以编辑 mogenerator 的人工文件以某种方式捕获调用,无论它们使用 KVC 还是方法调用,并返回一个如果字符串属性为零,则为空字符串。在类似的情况下,如果整数属性为零,我想返回一个空字符串。

这可能吗?还是我必须单独覆盖每个属性?

4

2 回答 2

3

听起来您真正想要的是将字符串属性的默认值设为空字符串。在大多数情况下,您可以在 Core Data 模型编辑器中为属性设置默认值。每当您创建新的托管对象时,该值都会自动分配给该属性。但是编辑器不支持使用空字符串作为默认值,所以你不能在那里做。

不过,您可以在运行时将默认值设为空字符串。数据模型是可编辑的,直到您开始使用它们。因此,在您创建模型对象之后立即执行此操作是一个好地方。以下将为数据模型中的每个字符串属性分配一个空字符串作为默认值:

- (NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];
    _managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];

    NSEntityDescription *entityDescription = [_managedObjectModel entitiesByName][@"Entity"];
    for (NSString *attributeName in [entityDescription attributesByName]) {
        NSAttributeDescription *attributeDesc = [entityDescription attributesByName][attributeName];
        if ([attributeDesc attributeType] == NSStringAttributeType) {
            [attributeDesc setDefaultValue:@""];
        }
    }

    return _managedObjectModel;
}

使用这个或类似的东西,当您创建新实例时,模型中的每个字符串属性都将自动为空字符串。如果您不想对每个字符串属性都执行此操作,请编辑代码以添加对实体和/或属性名称的一些额外检查。

于 2013-11-18T18:22:11.357 回答
0

我使用的是汤姆的解决方案,但方式略有不同。由于我使用 Magical Record 进行大部分核心数据访问,因此我的应用程序委托没有managedObjectModel属性。CVCAbstractEntity但是,通过在mogenerator生成的类中放入与他类似的代码,在-awakeFromInsert方法中,问题得到了很好的解决。

它在某种程度上不如 Tom 的解决方案优雅,因为虽然默认值确实应该是空字符串,但它在创建托管对象时将字符串属性设置为空字符串。但除非我想更改 Magical Record 类别的代码,否则此解决方案对我来说效果更好。

这是我添加到的代码-awakeFromInsert

NSManagedObjectModel *mom = [NSManagedObjectModel defaultManagedObjectModel];
NSEntityDescription *entityDesc = [[mom entitiesByName] objectForKey:[self entityName]];
for (NSString *attributeName in [entityDesc attributesByName]) {
  NSAttributeDescription *attrDesc = [[entityDesc attributesByName] objectForKey:attributeName];
  if ([attrDesc attributeType] == NSStringAttributeType) {
    [self setValue:@"" forKey:attributeName];
  }
}
于 2013-11-18T22:39:41.263 回答