【问题标题】:Properly handle the deletion of an object only if there are no relationships?只有在没有关系的情况下才能正确处理对象的删除?
【发布时间】:2011-02-13 03:43:02
【问题描述】:

我有一个Person 实体,它属于一对多关系中的Department

我希望能够在没有更多与之关联的Persons 时删除Department(通过删除Person 实体或更改Person 的@ 987654327@ 属性)。现在,我正在尝试使用NSManagedObjectContextObjectsDidChangeNotification 的以下处理程序来执行此操作(目前只是尝试查看删除,并适当地删除):

- (void)managedObjectDidChange:(NSNotification *)notification {

    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
    for (NSManagedObject *obj in updatedObjects) {
        if ([obj.entity.name isEqualToString:@"Person"]) {
            NSLog(@"Person Changed");

            NSManagedObject *department = [(Person *)obj department];
            NSLog(@"%i", [[department valueForKey:@"person"] count]);

            if ([[department] valueForKey:@"person"] count] == 0) {
                NSLog(@"Department has no more people associated with it");
                // deletion code
            }
        }
    }
}

但是,当我删除一个人时,与部门关联的人数并没有改变。我没有在 Department 实体上执行提取。这是我应该做的事情吗?

【问题讨论】:

  • 删除Person对象后是否保存上下文?
  • 是的,我删除了Person,保存了上下文,当我将NSLogPerson 关联的Personobjects 的计数与Department 关联时,什么都没有改变。

标签: cocoa cocoa-touch core-data nsmanagedobject nsmanagedobjectcontext


【解决方案1】:

最简单的方法:在你的部门实体类中实现willSave(你给每个实体一个自己的类,对吧?*),让你的部门检查自己的[self isDeleted] == NO[[self person] count] == 0,如果是的话,删除自己。 (isDeleted 的检查不是可选的,因为在willSave 内更改自身的实体会触发对 willSave 的另一个调用。NSManagedObject willSave 的文档有更多信息。)这会推迟删除,直到上下文刷新回磁盘,这应该不是什么大问题。

如果您确实需要部门在最后一个人离开时立即将其删除,请让您的部门实体使用 KVO 观察自身。在awakeFromFetchawakeFromInsert 中将其注册为自己的“person”属性的观察者,并在willTurnIntoFault 中取消注册。当 person 属性发生变化时,检查它是否为空。这是更多的工作,所以只有在第一种方法不适合你时才尝试。

最后,记住Person->Department关系删除规则需要设置为'nullify'(删除Person时,从Department的persons中删除),而不是'no action'(删除Person时,你取自己清理部门的责任)或“级联”(当任何人被删除时,其部门也被删除!)

(* MOGenerator 是维护每个实体类的好帮手。http://rentzsch.github.com/mogenerator/)

【讨论】:

  • 使用 KVO 让Department 观察自己的唯一问题是,当它出现故障时它没有在监听。如果最后一个Person 对象在Department 出错时被删除,那么您的对象图将受到损害。
【解决方案2】:

在您的 Person 子类中,覆盖 prepareForDeletion。如果Department 只剩下一个person,也请删除Department。 Apple 的文档甚至建议使用 prepareForDeletion 作为自定义删除传播的最佳位置。

- (void)prepareForDeletion
{
    [super prepareForDeletion];

    if (self.department.persons.count == 1) {
        [self.managedObjectContext deleteObject:self.department];
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多