我有两个A和B类,从A到B有多对一的关系(多个A对象可能引用相同的B)。问题是,如果A侧的删除规则是Cascade,则只有在最后引用A被删除时才删除B,或者删除第一次时间关联的A被删除。如果重要的话,关系B侧的删除规则是Nullify。
另外,我在Core Data文档中读到,Optional标志在某些情况下很重要。但目前尚不清楚他们所说的关系与我的案例有何关系。他们在讨论收容案(B由A拥有),而我的案例是订阅/关联(B与A有关)。
我可以简单地在代码中管理删除programmaticaly,但是如果可能的话,希望允许Core Data做正确的事情。但目前尚不清楚核心数据是否支持我正在寻找的垃圾收集语义。
有什么建议吗?
答案 0 :(得分:15)
我的目标与您显然相同(删除 B 后,删除最后一次引用的 A )。为了做到这一点,我花了比预期更长的时间。特别是因为
-prepareForDeletion
期间设置如果有人感兴趣的话,这对我有用(我将使用部门< - >> 员工,因为它更容易阅读):
在员工:
- (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];
}
}
}
其他人建议将此逻辑放入部门中的-willSave
。我更喜欢上面的解决方案,因为在某些情况下我可能真的想要保存一个空的部门(例如在手动存储迁移或数据导入期间)。
答案 1 :(得分:0)
这是Lukas答案的 Swift 4 版本:
public override func prepareForDeletion() {
guard let department = department else { return }
if department.employees.filter({ !$0.isDeleted }).isEmpty {
managedObjectContext?.delete(department)
}
}
答案 2 :(得分: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 {
}
}
}