Implementing Batch Deletes
Follow the implementation guidelines in this chapter to avoid common pitfalls and produce maintainable code. You will learn how to:
Set up a batch delete
Executie a batch delete
Update your application after execution
Impacts of Using a Batch Delete
Batch deletes run faster than deleting the Core Data entities yourself in code because they operate in the persistent store itself, at the SQL level. As part of this difference, the changes enacted on the persistent store are not reflected in the objects that are currently in memory.
After a batch delete has been executed, remove any objects in memory that have been deleted from the persistent store.
Validation Rules
When you execute a batch delete, any validation rules that are part of the data model are not enforced. Therefore, ensure that any changes caused by the batch delete will continue to pass the validation rules. This naturally impacts validation rules on relationships.
Setting Up a Batch Delete
The goal of a batch delete is to delete one or more specific entities that are stored in a SQLite persistent store. To start a batch update, you create an NSBatchDeleteRequest
that accepts an NSFetchRequest
as part of its initialization.
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee") |
fetch.predicate = NSPredicate(format: "terminationDate < %@", NSDate()) |
let request = NSBatchDeleteRequest(fetchRequest: fetch) |
When an NSBatchDeleteRequest
is created it accepts an NSFetchRequest
that describes which entities are to be deleted from the persistent store.
Executing a batch delete
After the NSBatchDeleteRequest
is constructed, it is executed against an NSManagedObjectContext
:
do { |
let result = try moc.executeRequest(request) |
} catch { |
fatalError("Failed to execute request: \(error)") |
} |
The call to executeRequest()
can throw an error and therefore requires the try
keyword. If the call fails, the error can be reported. When the executeRequest
completes successfully, a response is received. That response can take one of two forms. The form of the response is deteremined by setting the resultType
property on the NSBatchDeleteRequest
. The default value is NSStatusOnlyResultType
, which returns nothing.
The other option is NSBatchDeleteObjectIDsResultType
, which returns an array of NSManagedObjectID
instances indicating which entities were deleted during the execution.
The resultType
needs to be set prior to the execution of the NSBatchDeleteRequest
. Regardless of the resultType
that is set, the execution of the NSBatchDeleteRequest
returns an NSPersistentStoreResult
instance. If the resultType
is set to NSBatchDeleteObjectIDsResultType
, the value of the result property inside of the NSPersistentStoreResult
instance is set.
Updating Your Application After Execution
If the entities that are being deleted are not loaded into memory, there is no need to update your application after the NSBatchDeleteRequest has been executed. However, if you are deleting objects in the persistence layer and those entities are also in memory, it is important that you notify the application that the objects in memory are stale and need to be refreshed.
To do this, first make sure the resultType
of the NSBatchDeleteRequest
is set to NSBatchDeleteRequestResultType.resultTypeObjectIDs
before the request is executed. When the request has completed successfully, the resulting NSPersistentStoreResult
instance that is returned will have an array of NSManagedObjectID
instances referenced in the result property. That array of NSManagedObjectID
instances can then be used to update one or more NSManagedObjectContext
instances.
do { |
let result = try moc.execute(request) as? NSBatchDeleteResult |
let objectIDArray = result?.result as? [NSManagedObjectID] |
let changes = [NSDeletedObjectsKey : objectIDArray] |
NSManagedObjectContext.mergeChangesFromRemoteContextSave(changes, [moc]) |
} catch { |
fatalError("Failed to perform batch update: \(error)") |
} |
By calling mergeChangesFromRemoteContextSave
, all of the NSManagedObjectContext
instances that are referenced will be notified that the list of entities referenced with the NSManagedObjectID
array have been deleted and that the objects in memory are stale. This causes the referenced NSManagedObjectContext
instances to remove any objects in memory that are loaded which match the NSManagedObjectID
instances in the array.
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13