23

我有两个类 A 和 B,从 A 到 B 具有多对一的关系(多个 A 对象可能引用同一个 B)。问题是,如果A端的删除规则是Cascade,那么B只有在最后一个引用A被删除时才会被删除,还是在关联的A第一次被删除时才被删除。如果重要,关系 B 方的删除规则是 Nullify。

此外,我在 Core Data 文档中读到 Optional 标志在某些情况下很重要。但不清楚他们所说明的关系与我的案件有何关系。他们在谈论一个遏制案例(B 归 A 所有),而我的案例是订阅/关联之一(B 与 A 有关)。

我可以简单地在代码中以编程方式管理删除,但如果可能的话,我希望允许 Core Data 做正确的事情。但目前尚不清楚我正在寻找的垃圾收集语义是否在 Core Data 中得到支持。

有什么建议么?

4

3 回答 3

16

我的目标显然与您的目标相同(删除最后一个引用的 A后立即删除B)。我花了比预期更长的时间才能做到这一点。特别是因为

  • A准备删除的时候, B中的一对多关系可能还没有更新,所以你不能只计算B中引用的A
  • 在A上的isDeleted似乎已经在-prepareForDeletion

如果有人感兴趣,这对我有用(我会使用Department <-->> Employee因为它更容易阅读):

员工中:

- (void)prepareForDeletion {
    // Delete our department if we we're the last employee associated with it.
    Department *department = self.department;
    if (department && (department.isDeleted == NO)) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isDeleted == NO"];
        NSSet *employees = [department.employees filteredSetUsingPredicate:predicate];

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

其他人建议将此逻辑放入Department-willSave。我更喜欢上面的解决方案,因为在某些情况下(例如在手动存储迁移或数据导入期间)我可能实际上想要保存一个空部门。

于 2012-12-04T11:40:16.270 回答
1

这是Lukas 答案的Swift 4版本:

public override func prepareForDeletion() {
    guard let department = department else { return }

    if department.employees.filter({ !$0.isDeleted }).isEmpty {
        managedObjectContext?.delete(department)
    }
}
于 2017-10-08T13:38:00.093 回答
0

添加到@JanApotheker 答案,您还需要保存 managedObjectContext 并将过滤器的参数转换为 AnyObject,因为它像这样遍历 NSSet:-

public override func prepareForDeletion() {
    guard let department = department, let employees = department.employees else { return }

    if employees.filter({ !($0 as AnyObject).isDeleted }).isEmpty {
        managedObjectContext?.delete(department)
        do {
            try managedObjectContext?.save()
        } catch {
            
        }
    }
}
于 2021-07-13T12:40:41.280 回答