Core Data中是否可以自动删除未引用的对象?

问题描述 投票:0回答:3

我的数据模型包含两个实体:作者和书籍,具有一对多关系(一位作者可能写多本书)。

假设 DB 中只有两本书和两位作者,如下所示:

  • 书籍 A 已分配给作者 X
  • 书籍 B 分配给作者 Y

假设应用以下更改:

  • 书籍 B 被分配给新作者 Z。

结果:

  • 作者 Y 存在于数据库中,但没有指向任何书。

我的问题:是否可以配置数据模型,以便像作者 Y 这样的对象在没有被任何书籍引用时自动删除?

iphone ios ios4 core-data entity-relationship
3个回答
2
投票

查看“删除传播”。它正是为了解决这个问题。

如果这不能完全满足您的需求:您可以覆盖 Book 实体上的

- (void)prepareForDeletion
,然后检查是否有任何已在上下文中注册并有待更改的作者(因为它们的逆值将发生更改)并且没有书:

{
    // ...
    [[NSNotificationCenter defaultNotificationCenter] addObserver:self selector:@selector(deleteOrphanedAuthors:) name:NSManagedObjectContext object:moc];
    // ...
}

- (void)deleteOrphanedAuthors:(NSNotification *)note;
{
    NSManagedObjectContext *moc = [note object];
    NSManagedObjectModel *mom = [[moc persistentStoreCoordinator] managedObjectModel];
    NSEntityDescription *authorEntity = [[mom entitiesByName] objectForKey:@"Author"];
    for (NSManagedObject *author in [moc updatedObjects]) {
        if ([author entity] == authorEntity) {
            if (![author hasFaultForRelationshipNamed:@"books"] && ([[author books] count] == 0)) {
                [moc deleteObject:author];
            }
        }
    }
}

注意:您可以

nil
作为要观察的对象(即上下文)传递,因为您使用的框架可能有自己的上下文,并且您不想弄乱它们。

另外,请注意此代码如何小心地避免触碰

author
对象(如果出现故障)。如果删除一本书,Core Data 将更改相应作者对象的反向关系,从而使该关系出现故障,从而不再是故障。并且代码只会对这些对象进行操作。


1
投票

您需要手动确定“孤儿”书籍。

当您更新作者关系时,您可以检查旧

Author
的书籍关系,看看它是否还有书籍。

或者,您可以使用通知来确定

NSManagedObjectContext
何时更改:
NSManagedObjectContextObjectsDidChangeNotification
。如果您注册此通知,您可以检查
Author
对象的许多更改。查看文档中的特定通知


0
投票

创建这个子类...

open class SaveObservingManagedObject: NSManagedObject {
  override public init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
    super.init(entity: entity, insertInto: context)

  NotificationCenter.default.addObserver(forName: NSNotification.Name.NSManagedObjectContextWillSave,
                                           object: nil,
                                           queue: .current,
                                           using: { [weak self] _ in
                                             self?.onWillSave()
                                           })
  }

  open func onWillSave() {
    fatalError("Super class is expected to override this function")
  }
}

然后对于您想要在孤立时自动删除的实体,您可以执行类似的操作...

final class ChildEntity: SaveObservingManagedObject {
  @NSManaged var someProperty: String?

  // Owner relationships
  @NSManaged private var parent: ParentEntity?

  override func onWillSave() {
    // Delete entity if orphaned
    if !isDeleted, event == nil {
      managedObjectContext?.delete(self)
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.