4

I am changing my CoreData setup to have 2 NSManagedObjectContexts under 1 NSPersistentStoreCoordinator.

  1. The Root Context is NSManagedObjectContext instantiated with NSPrivateQueueConcurrencyType and set to NSMergeByPropertyStoreTrumpMergePolicy
  2. The Main Context is NSManagedObjectContext instantiated with NSMainQueueConcurrencyType also set to a NSMergeByPropertyStoreTrumpMergePolicy

Both of them are not connected by "parent-and-child" relationship, however they are assigned the same NSPersistentStoreCoordinator object. The Main Context is listening to the Root Context's NSManagedObjectContextDidSaveNotification notification and do the necessary merging inside performBlock:

Occasionally, when an instance of NSFetchedResultsController is hooked with the Main Context does a performFetch I got

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'statement is still active'

I am wondering if what I'm about to do here should not be done or a limitation of Core Data.

Thanks

Rpranata
  • 2,010
  • 18
  • 24

1 Answers1

4

Florian Kugler wrote a good article about this: The Concurrent Core Data Stack

The idea is to import your data in a private-queue context (Import Context) which is child of the Main Context.

This Main Context is on the main queue (I like to call it UI queue), so you can use objects out of it in the main thread (UI thread) without having to convert them from a private thread to the main thread.

Finally, the Main Context is child of your Root Context which runs in its own private queue. That way saves will be done in a background thread and not block your UI.

Since in this setup you never touch the [Root Context], i.e. you never directly make changes to it, all changes flow through the main context. Therefore you will always have the latest data available on the main thread. No need for listening to change notifications and merging changes manually.

I would not worry about performance in the first place. Core Data is heavily optimised and if performance problems arise then you can decrease lower the amount of data a single import worker saves.

Mark Gaensicke
  • 504
  • 5
  • 16
  • Good point, thanks @Mark. In fact this is the current model that I have but since all the of the changes (when is saved up through the chain) needs to go through the **UI Queue**, I felt some UI (i.e animation) being jerky. So I was thinking of trying different ways on how to improve it. Might not be the best approach after all. – Rpranata Sep 16 '15 at 11:46
  • You can't really get around it because you want your UI to be up to date anyway. So you have to let Core Data perform its duty. If you experience slowness, use instruments to detect performance issues and fix them one at a time. Always keep import worker load small and save in batches of around 500-5000 items (depending on complexity). – Mark Gaensicke Sep 16 '15 at 11:48
  • I think it depends on the use case but in our app, we dont mind sacrificing some delay getting data presented in the UI then having to experiencing UI jerkiness. I ll have a play around but thanks a lot for the suggestion. – Rpranata Sep 16 '15 at 23:39