Search code examples
iosswiftcore-datansmanagedobjectcontext

CoreData: difference between backgroundContext and child context with privateQueueConcurrencyType?


With CoreData you can ask the container to create a background context with container.newBackgroundContext().

This is useful for use core data in background without impact on the UI main context.

You can also create a child context with privateQueueConcurrencyType

let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)

In this case if I'm not wrong, the context will still execute in background on a different queue.

So what's the difference between the two and when to use one and the other one?


Solution

  • Your initialization of a context, namely:

    let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
    

    was commonly used before the introduction of NSPersistentContainer. See also https://developer.apple.com/documentation/coredata/using_core_data_in_the_background, where they state:

    Initializing and Configuring Contexts For both contexts, the initialization of the NSManagedObjectContext instance is the same: let moc = NSManagedObjectContext(concurrencyType:<#type#>) The parameter being passed in as part of the initialization determines what type of NSManagedObjectContext is returned. When you use the NSPersistentContainer, you configure the viewContext property as a main queue (NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType) context, and configure the contexts associated with performBackgroundTask(_:) and newBackgroundContext() as a private queue (NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType).

    The documentation of newBackgroundContext() says the following:

    Invoking this method causes the persistent container to create and return a new NSManagedObjectContext with the concurrencyType set to NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType. This new context will be associated with the NSPersistentStoreCoordinator directly and is set to consume NSManagedObjectContextDidSave broadcasts automatically.

    newBackgroundContext() does the same as your provided code, and something extra that I have highlighted in the above quote.

    When developing for iOS 10+, I would recommend using NSPersistentContainer and use newBackgroundContext() when you want to block the calling thread, or performBackgroundTask if you do not want to calling thread to block when you want to dispatch work to the background.

    I haven't worked with CoreData before iOS 10, but I think you need to do more stuff to make the context work when initializing it just with a concurrenyType. That isn't needed anymore with newBackgroundContext().