是否有一个好地方可以捕获 Core Data 属性检索以用空字符串覆盖 nil 字符串?

Posted

技术标签:

【中文标题】是否有一个好地方可以捕获 Core Data 属性检索以用空字符串覆盖 nil 字符串?【英文标题】:Is there a good place to capture Core Data attribute retrieval to override nil string with empty strings instead? 【发布时间】:2013-11-18 17:03:42 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

听起来您真正想要的是将字符串属性的默认值设为空字符串。在大多数情况下,您可以在 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;

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

【讨论】:

这很方便,想必这对模型版本没有影响吧? 否,默认值不影响模型版本。 那些对类似但替代解决方案感兴趣的人应该在下面看到我的答案。【参考方案2】:

我使用的是 Tom 的解决方案,但方式略有不同。由于我使用 Magical Record 进行大部分核心数据访问,因此我的应用程序委托没有 managedObjectModel 属性。不过,通过在mogenerator生成的CVCAbstractEntity类中放入与他类似的代码,在-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];
  

【讨论】:

您可以修改您的 Magical Record 副本以使用默认值。它也会创建一个NSManagedObjectModel,并且你有源代码。 我确实想到了这一点,以后可能会做类似的事情,但我是 Cocoa 的初学者,不希望有机会弄乱工作代码。

以上是关于是否有一个好地方可以捕获 Core Data 属性检索以用空字符串覆盖 nil 字符串?的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 属性的自定义 Getter

Core Data 没有触发 NSManagedObject 实例的错误作为应用程序委托的属性

如何从 Core Data 中删除具有特定属性的项目?

Core Data 可以在 iOS 上延迟获取 BLOB 属性吗?

iOS Core Data:使用 Foundation 对象添加属性

如何使用合并策略捕获Core Data中的错误