ios - 核心数据 : parent context blocks child

标签 ios multithreading core-data nsmanagedobjectcontext

我正在使用核心数据在应用程序中进行一些后台处理。后台处理是在子 managedObjectContext 上完成的。上下文初始化:

appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

// the moc in appDelegate is created with .MainQueueConcurrencyType
mainThreadMOC = appDelegate.managedObjectContext!
backgroundMOC = NSManagedObjectContext(concurrencyType:NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
backgroundMOC?.parentContext = mainThreadMOC

后台处理通过以下方法完成:

// download all new transaction log entries
func syncItems() {

... set up the query object for parse

let moc = CoreDataStore.sharedInstance.backgroundMOC

// perform download
moc?.performBlock( {
    self.runQuery(query)   // Download stuff und do some core data work
    })
}

调试器显示 block 内的所有工作确实在后台线程中进行。

当我从主线程调用此函数并立即用冗长的核心数据操作阻塞主线程(用于测试目的)时,我看到后台线程停止并仅在主线程空闲时继续执行。

// this is called from a view controller in the main thread

syncItems() // should start to work in background
for i in 0...200 {
    // do some core data work in main thread
}
// syncItems starts to work after the blocking for-loop ends.

为什么会这样?

最佳答案

不要使用父子上下文设置。

父子上下文对于任何事情都不是一个好的方法。只需使用一个简单的堆栈:两个上下文和一个共享的持久存储协调器。

父子上下文只会增加很多困惑,而不会给您带来任何好处。这是一个很容易被误解的概念。我希望像 mzarra 这样的人 f***ing 停止提倡这种设置。这是对社区的损害。

如果您的后台上下文是主上下文的子上下文,则无论何时后台上下文需要保存,您都必须锁定主上下文和后台上下文。这会阻止 UI。并且您必须第二次锁定 UI 才能将这些更改从 UI 传播到 PSC。如果您使用后台上下文,则必须将更改合并到主上下文中,但您只会为那些当前在该上下文中注册的对象工作。如果您添加了新对象,或者更新/删除了当前未注册(引用)的对象,那基本上是空操作。

关于ios - 核心数据 : parent context blocks child,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29900193/

相关文章:

c - 单线程 OpenMP 与顺序的开销

c# - 我应该在编写任何锁之前对多线程问题进行单元测试吗?

c++ - IF 的原子性和下面的语句

ios - 应用程序委托(delegate)的 Swift Xcode 7 错误

ios - 使用 RKEntityMapping 和 RKRelationshipMapping 获取多条记录

ios - 代码简化 Objective-C

ios - 通过自定义导航栏 setBackgroundImage 查看偏移量

ios - 如何从全局范围更改 socket 属性?

ios - CollectionViewCell 中 UITextField 的输入(swift 3 xcode)

ios - WatchOS 存储和共享数据