iPhone Core Data: Cascading delete across a many-to-one relationship

青春壹個敷衍的年華 提交于 2019-11-30 00:11:38

I had the same goal as you apparently had (delete B as soon as the last referenced A is deleted). It took me longer than expected to get this right. Particularly because

  • At the time A prepares for deletion, the to-many relationship in B might not be updated yet, so you can't just count the A referenced in B.
  • isDeleted on A seems to be already set during -prepareForDeletion

Here's what worked for me if anybody's interested (I'll use Department <-->> Employee because it's easier to read):

In 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];
        } 
    }
}

Other people have suggested putting this logic into -willSave in Department. I prefer the solution above since I might actually want to save an empty department in some cases (e.g. during manual store migration or data import).

Here's a Swift 4 version of Lukas' answer:

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

    if department.employees.filter({ !$0.isDeleted }).isEmpty {
        managedObjectContext?.delete(department)
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!