ios – 如何在使用嵌套上下文时自动设置Core Data关系

我正在努力找出一个体面的解决方案,在核心数据中使用嵌套的管理对象上下文时出现的问题.拿一个有两个人的人物和名字的模型,每个人与一个名字有一对一的关系,而名字的人际关系不是可选的.以前,在Person的-awakeFromInsert方法中,我会为新的Person自动创建一个Name实体:
- (void)awakeFromInsert
{
    [super awakeFromInsert];

    NSManagedobjectContext *context = [self managedobjectContext];
    self.name = [NSEntityDescription insertNewObjectForEntityForName:@"Name" inManagedobjectContext:context];
}

这在单个非嵌套管理对象上下文中工作得很好.但是,如果上下文具有父上下文,则当保存子上下文时,将在父上下文中创建一个新的Person对象,并且在原始Person的属性和关系被复制之前,再次调用此新对象的-awakeFromInsert.因此,创建另一个Name对象,然后在现有的名称关系复制时“断开连接”.保存失败,因为验证浮动名称现在无关联关系失败.这个问题描述在here以及其他地方.

到目前为止,我无法想出这个问题的一个很好的解决方案.在getter方法中懒洋洋地创建关系实际上会导致同样的问题,因为当在父上下文中创建新Person时,内部Core Data机器调用getter.

我唯一可以想出的是放弃自动关系生成,并且始终在创建Person的控制器类中明确创建关系,或者在一个方便的方法(例如[Person insertNewPersonInManagedobjectContext:])中创建关系,这个方法只能被我的代码,并且始终是用于显式创建新Person对象的方法.也许这是最好的解决方案,但是我宁可不必那么严格,只允许使用单一的方法来创建管理对象,当我无法控制的其他创建方法,我无法使用它容易检查/排除,存在.首先,它将意味着多个NSArrayController子类来自定义他们创建管理对象的方式.

遇到这个问题的其他任何人都想出了一个优雅的解决方案,允许一个NSManagedobject在创建/插入时自动创建关系对象?

解决方法

想到的第一个想法是,虽然姓名的人际关系是不可选的,但你并没有说Person的姓名关系也是不可选的.创建一个没有名字的人,可以用您的代码处理,然后在实际需要时创建名称吗?

如果没有,一个简单的方法就是在创建一个名字之前检查你是否在根上下文中:

- (void)awakeFromInsert
{
    [super awakeFromInsert];

    NSManagedobjectContext *context = [self managedobjectContext];
    if ([context parentContext] != nil) {
        self.name = [NSEntityDescription insertNewObjectForEntityForName:@"Name" inManagedobjectContext:context];
    }
}

但是,如果您始终在子上下文中创建新实例,并且您不会嵌套多于一个级别的上下文,那么该方法才起作用.

我可能会做的是创建一个方法,如insertNewPersonInManagedobjectContext:你描述的.然后用以下内容补充以处理为您创建实例(即数组控制器)的任何情况:

- (void)willSave
{
    if ([self name] == nil) {
        NSManagedobjectContext *context = [self managedobjectContext];
        Name *name = [NSEntityDescription insertNewObjectForEntityForName:@"Name" inManagedobjectContext:context];
        [self setName:name];
    }
}

…当然不用打扰自定义awakeFromInsert …

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...