使用 Core Data 从后台线程获取

Posted

技术标签:

【中文标题】使用 Core Data 从后台线程获取【英文标题】:Fetching from background thread with Core Data 【发布时间】:2020-12-01 14:30:27 【问题描述】:

我想从后台线程获取数据以提高性能。我怎样才能做到这一点?我在任何地方都找不到帮助。

目前,我正在像这样获取我的数据:

do 
    let items = try mainContext.fetch(Item.fetchRequest())
    return items
 catch  ... 

据我了解,我无法在后台线程上运行上述代码,因为主上下文绑定到主线程。所以这是不可能的:

DispatchQueue.global().async 
    do 
        let items = try mainContext.fetch(Item.fetchRequest())
        completion(items)
     catch  ... 

所以我尝试在这样的背景上下文中执行此操作:

let backgroundContext = container.newBackgroundContext()
backgroundContext.parent = mainContext

backgroundContext.perform 
    do 
        let items = try backgroundContext.fetch(Item.fetchRequest())
        DispatchQueue.main.async  completion(items) 
     catch  ... 

但不幸的是,这似乎也不起作用。

任何帮助将不胜感激。 非常感谢!

【问题讨论】:

【参考方案1】:

据我了解,我无法在后台线程上运行上述代码,因为主上下文绑定到主线程。

上下文不是“绑定”到线程,而是您需要确保对给定上下文的操作正确序列化。因此,您可以将主上下文传递到后台操作并将其用于获取,但您需要避免使用主线程中的主上下文,直到该后台操作完成。这种配合很容易出错,最好避免。

让 backgroundContext = container.newBackgroundContext() backgroundContext.parent = mainContext

这应该可以工作,并且能够在后台运行并共享结果是托管对象上下文具有parent 的原因之一。但是,您在backgroundContext 中所做的更改在您保存之前不会在mainContext 中可见。在您显示的代码中没有调用save(),所以这可能是问题的一部分。

我想从后台线程获取数据以提高性能。

在您走得太远之前,请确保您确实需要这样做。 Core Data 可以非常快,而且由于您通常不能同时显示大量数据,因此一次获取所有结果通常没有意义。如果您获取的对象数量较少,您可能会获得所需的性能改进,而无需担心后台操作。

【讨论】:

太棒了,保存成功了!但正如你所提到的,因为我最多有大约 20 个条目要获取......我不应该担心后台操作。非常感谢,这非常有用,大大增加了我的理解。

以上是关于使用 Core Data 从后台线程获取的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 使用多个上下文中的新对象从后台线程订购一对多关系保存

Core Data,在后台线程中修改 NSManagedObject

Core Data 3 托管对象上下文

Core-Data 后台保存性能问题

在后台线程上安全保存 Core Data 托管对象上下文的正确方法?

Core Data undo后台线程删除