9

I'm familiarizing myself with NSPersistentContainer. I wonder if it's better to spawn an instance of the private context with newBackgroundContext every time I need to insert/fetch some entities in the background or create one private context, keep it and use for all background tasks through the lifetime of the app.

The documentation also offers convenience method performBackgroundTask. Just trying to figure out the best practice here.

Ross Stepaniak
  • 877
  • 1
  • 6
  • 22

1 Answers1

8

I generally recommend one of two approaches. (There are other setups that work, but these are two that I have used, and tested and would recommend.)

The Simple Way

You read from the viewContext and you write to the viewContext and only use the main thread. This is the simplest approach and avoids a lot of the multithread issues that are common with core-data. The problem is that the disk access is happening on the main thread and if you are doing a lot of it, it could slow down your app.

This approach is suitable for small lightweight application. Any app that has less than a few thousand total entities and no bulk changes at once would be a good candidate for this. A simple todo list, would be a good example.

The Complex Way

The complex way is to only read from the viewContext on the main thread and do all your writing using performBackgroundTask inside a serial queue. Every block inside the performBackgroundTask refetches any managedObjects that it needs (using objectIds) and all managedObjects that it creates are discarded at the end of the block. Each performBackgroundTask is transactional and saveContext is called at end of the block. A fuller description can be found here: NSPersistentContainer concurrency for saving to core data

This is a robust and functional core-data setup that can manage data at any reasonable scale.

The problem is that you must always make sure that the managedObjects are from the context you expect and are accessed on the correct thread. You also need a serial queue to make sure you don't get write conflicts. You will also need to use fetchedResultsController on the main thread to make sure entities are not deleted while you are holding pointers to them.

Jon Rose
  • 8,373
  • 1
  • 30
  • 36
  • 1
    Hi @Jon Rose ,can you point me to a demo of doing things the complex way, as you mentioned above? – Sagar D Sep 17 '18 at 09:12
  • Sure! You can find a fuller explanation the answer to this question: https://stackoverflow.com/questions/42733574/nspersistentcontainer-concurrency-for-saving-to-core-data – Jon Rose Sep 17 '18 at 10:10