简体   繁体   中英

Is it possible to delete unreferenced objects automatically in Core Data?

My data model contains two entities: Author and Book with a one to many relationship (one author may write several books).

Let's say that there are only two books and two authors in DB as follows:

  • Book A is assigned to Author X
  • Book B is assigned to Author Y

Assuming following change is applied:

  • Book B is assigned to a new Author Z.

Result:

  • Author Y exists in DB but points to no book.

My question: is it possible to configure the data model so objects like Author Y will be automatically deleted when they are not referenced by any book?

Check out "delete propagation". It's there to solve exactly that problem.

If that doesn't do exactly what you want / need: You can override - (void)prepareForDeletion on the Book entity and at that point check for any Authors that are registered with the context and have pending changes (since their inverse will have changed) and have no books:

{
    // ...
    [[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];
            }
        }
    }
}

Note: You can not pass nil as the object (ie context) to observe, since frameworks you use, might have their own context, and you do not want to mess with them.

Also, note how this code is careful not to touch the author object if it's a fault. If a book is deleted, Core Data will change the corresponding author objects' inverse relationships, hence fault in that relationship, such that it is no longer a fault. And the code will only operate on those objects.

You will need to determine "orphaned" books manually.

When you update the Author relationship you could check the old Author 's books relationship to see if it still has any books.

Alternatively you could use notifications to determine when the NSManagedObjectContext changes: NSManagedObjectContextObjectsDidChangeNotification . If you register for this notification you can check for a number of changes to Author objects. Have a look at that specific notification in the docs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM