After executing an NSBatchBatchInsertRequest
and calling fetchedResultsController.performFetch()
, the frc’s delegate method controller(_:didChangeContentWith:)
is called with a NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>
that unexpectedly contains all data in Core Data.
However I've only just inserted new data into Core Data. Applying a snapshot with all the data at each performFetch
is causing a high memory load and jittery scrolling when I test this with thousands of cells.
Is there a way to make this delegate method only receive a snapshot with incremental updates to the data source?
Code
Here's how the NSFetchedResultsController
is created:
let fetchedResultsController = NSFetchedResultsController<MyManagedObject>(
fetchRequest: fetchRequest,
managedObjectContext: persistentContainer.viewContext,
sectionNameKeyPath: nil,
cacheName: nil
)
The NSFetchRequest
:
let fetchRequest = MyManagedObject.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "value", ascending: true)]
fetchRequest.fetchBatchSize = 10
The snapshot is applied in this NSFetchedResultsControllerDelegate
method below.
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
dataSource.apply(snapshot as NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>, animatingDifferences: false)
}
The most obvious solution to me was implementing this delegate method only, but that method doesn't seem to get called:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith diff: CollectionDifference<NSManagedObjectID>) {
print(diff)
}
Data source to Core Data connection
- When the data source is asked to make a cell for a specific
NSManagedObjectID
, the rightMyManagedObject
is found for thatNSManagedObjectID
usingfetchedResultsController.managedObjectContext.object(with:)
. - Then the
MyManagedObject
is converted into anItem
, which is finally used to configure the cell.