Set shouldDeleteInaccessibleFaults: to YES , and invalid / non-executable errors will be removed. This solves the immediate problem.
WWDC 2015 session What's new in Core Data says a little about this. Both NSBatchDeleteRequest and NSBatchUpdateRequest modify persistent storage without the involvement of NSManagedObjectContext , which will result in the context view of the data being incompatible with the storage.
A copy of the deleted object in memory must be updated in NSManagedObjectContext - if the package deletion request returns the identifiers of the objects of the deleted objects and tells NSManagedObjectContext update these identifiers.
It will look something like this:
[managedObjectContext performBlock:^{ NSBatchDeleteRequest batchDeleteRequest = [NSBatchDeleteRequest alloc] initWithFetchRequest:fetchRequest]; NSBatchDeleteResult result = nil; result = [managedObjectContext executeRequest:batchDeleteRequest error:&error]; if ([[result result] count] > 0){ [managedObjectContext performBlock:^{ NSArray<NSManagedObjectID *> *objectIDs = (NSArray<NSManagedObjectID *>)[result result]; [objectIDs enumerateObjectsUsingBlock:^(NSManagedObjectID *objID, NSUInteger idx, BOOL *stop) { NSError *error = nil; NSManagedObject *obj = [managedObjectContext existingObjectWithID:objID error:&error]; if (![obj isFault] ) { [managedObjectContext refreshObject:obj mergeChanges:YES]; } }]; }]; } }];
When batch deletion starts, the relations will be deleted or canceled, but the cascading set of deletion rules may not be executed, and the verification rules will not be fulfilled - it depends on your application to ensure data integrity when using any of the batch change requests.
In your data model, you may need to issue multiple delete requests to prevent related objects from being lost, but can still be found. For example, you might need a second package deletion to search for previously related objects that now have empty relationships. A predicate for such a query might look like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@" toMany.@count == 0"];
Or may use a subquery, etc.
source share