Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreData: What's the difference between performBackgroundTask and newBackgroundContext()?

What's the difference between these two approaches?

container.performBackgroundTask { (context) in 
    // ... do some task on the context

    // save the context
    do {
        try context.save()
    } catch {
        // handle error
    }
}

and

let context = persistentContainer.newBackgroundContext()
context.perform {
    // ... do some task on the context

    // save the context
    do {
        try context.save()
    } catch {
        // handle error
    }
}

When to use the first and when to use the second approach?

like image 988
swalkner Avatar asked Dec 05 '18 13:12

swalkner


2 Answers

The difference is how concurrency is handled.

With performBackgroundTask...

container.performBackgroundTask { (context) in 
    // ... do some task on the context
}

The container creates a new background context to perform the task. This function returns immediately, so if you call it again before the task completes, both tasks could be running at the same time.

With newBackgroundContext...

let context = persistentContainer.newBackgroundContext()
context.perform {
    // ... do some task on the context
}

You create a new context and do some stuff in the background. If you call context.perform again on the same context that new closure also runs in the background. But since it's the same context, the second one doesn't start until the first one finishes.

What it comes down to is that the first can have many background contexts working at the same time while the second makes it easier to ensure that there's only one.

The first option can have more simultaneous background tasks, which might be good, but it might also mean that the multiple calls have conflicting changes. The second option serializes the background tasks, and since they don't run simultaneously they won't conflict with each other. Which is better depends on what you're doing in the closures.

like image 103
Tom Harrington Avatar answered Sep 19 '22 13:09

Tom Harrington


Not detailed answer but difference is

To avoid blocking the user interface you should not use the main view context for time consuming tasks. Create a private managed object context and execute the task in the background

container.performBackgroundTask --> It will create temporary private context for you and takes a block to execute

and

persistentContainer.newBackgroundContext --> You can also just get a new private context to use anyway you see fit:

Source https://useyourloaf.com/blog/easier-core-data-setup-with-persistent-containers/

like image 23
Prashant Tukadiya Avatar answered Sep 18 '22 13:09

Prashant Tukadiya