My app (unit test) is stalling when I call save()
in an NSManagedObjectContext
's private queue, originating from a separate background queue. It is a normal Core Data stack (with an in-memory persistent store for the unit tests).
Isn't the whole point of a private-queue context that you shouldn't be concerned about what queue an operation comes from? How should I resolve this?
I haven't been able to reproduce it in isolation, but here's a rough idea of my setup (pseudo-Swift, condensing calls across multiple classes):
let store = inMemoryStoreCoordinator()
let mainContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
mainContext.persistentStoreCoordinator = store
let childContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
childContext.parentContext = mainContext
let q = NSOperationQueue()
let group = dispatch_group_create()
q.addOperationWithBlock {
dispatch_group_enter(group)
childContext.performBlock {
try! childContext.save()
dispatch_group_leave(group)
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
I realized what's causing the deadlock. I'm using a dispatch group to lock the main thread, and apparently when the child context goes to save to its parent context (a Main Queue context), that's causing the deadlock.