从后台队列调用时,核心数据 NSManagedObjectContext 从不保存 returns

Core Data NSManagedObjectContext save never returns when called from a background queue

当我在 NSManagedObjectContext 的专用队列中调用 save() 时,我的应用程序(单元测试)停止运行,源自单独的后台队列。它是一个普通的核心数据堆栈(带有用于单元测试的内存中持久存储)。

私有队列上下文的全部意义不是您不应该关心操作来自哪个队列吗?我该如何解决?

我无法单独重现它,但这是我的设置的粗略想法(伪Swift,跨多个 类 压缩调用):

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)

这可能有多种原因,但 none 我们可以从提供的代码中推断出这一点。幸运的是,应该相当容易调试,只需在死锁(很可能)发生后暂停调试器,看看正在等待什么。这可能是上下文合并死锁,我会把钱花在上面。

我意识到是什么导致了僵局。我正在使用调度组锁定主线程,显然当子上下文保存到其父上下文(主队列上下文)时,这会导致死锁。