Apple has shown us how to perform heavy write operation using background thread (by using newBackgroundContext) in their official earth quake example - https://github.com/yccheok/earthquakes-WWDC20
But, what about heavy read operation? (millions of rows for stress test purpose)
We would also like our app UI to be responsiveness, when we are launching the app for first time, and the app is reading a large amount of data from CoreData.
The following is the code snippet which is using NSFetchedResultController.
[UI is not responsiveness if there are a lot of rows]
[UI is not responsiveness if there are a lot of rows]
We try to perform controller.performFetch() using background thread. Still, but not sure why, the UI is still not responsiveness. My guess is that, after NSFetchedResultsController is occupied UI main thread, to perform some time consuming I/O read operation.
[UI is responsive now. But the solution is incorrect...]
I guess, we need to place NSFetchedresultController under background thread too. Hence, we do the following modification.
The UI is responsiveness during fetching, and data is able to be fetched and shown after some time.
However, if we investigate further by using the launching argument
We will experience the following crash after controller.performFetch() finish executed.
May I know, is it ever possible to make UI responsive, when we are using NSFetchedResultController to load a large amount of data (few millions rows as per testing)?
Can NSFetchedResultController ever operated under background thread?
But, what about heavy read operation? (millions of rows for stress test purpose)
We would also like our app UI to be responsiveness, when we are launching the app for first time, and the app is reading a large amount of data from CoreData.
The following is the code snippet which is using NSFetchedResultController.
[UI is not responsiveness if there are a lot of rows]
Code Block let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil) controller.delegate = fetchedResultsControllerDelegate // Perform the fetch. do { // This statement tooks some time to complete if you have a lot of rows. try controller.performFetch() } catch { fatalError("Unresolved error \(error)") }
[UI is not responsiveness if there are a lot of rows]
We try to perform controller.performFetch() using background thread. Still, but not sure why, the UI is still not responsiveness. My guess is that, after NSFetchedResultsController is occupied UI main thread, to perform some time consuming I/O read operation.
Code Block let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil) controller.delegate = fetchedResultsControllerDelegate DispatchQueue.global(qos: .background).async { // Perform the fetch. do { // This statement tooks some time to complete if you have a lot of rows. try controller.performFetch() } catch { fatalError("Unresolved error \(error)") } }
[UI is responsive now. But the solution is incorrect...]
I guess, we need to place NSFetchedresultController under background thread too. Hence, we do the following modification.
Code Block let backgroundContext = persistentContainer.newBackgroundContext() let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: backgroundContext, sectionNameKeyPath: nil, cacheName: nil) controller.delegate = fetchedResultsControllerDelegate backgroundContext.perform { // Perform the fetch. do { // This statement tooks some time to complete if you have a lot of rows. try controller.performFetch() } catch { fatalError("Unresolved error \(error)") } }
The UI is responsiveness during fetching, and data is able to be fetched and shown after some time.
However, if we investigate further by using the launching argument
Code Block -com.apple.CoreData.ConcurrencyDebug 1
We will experience the following crash after controller.performFetch() finish executed.
Code Block CoreData`+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
May I know, is it ever possible to make UI responsive, when we are using NSFetchedResultController to load a large amount of data (few millions rows as per testing)?
Can NSFetchedResultController ever operated under background thread?