当前位置: 首页 > 知识库问答 >
问题:

CoreData-backgroundContext的使用

龙志勇
2023-03-14

我试图理解CoreData中的backgroundContext的概念。虽然我读了几篇关于它的文章,但我仍然不确定它的目的。

我有一个应用程序使用核心数据,允许用户创建,更新或删除记录。用户还可以获取他添加的数据。我想确保如果有很多记录,在获取数据时不会影响UI的流。

所以我研究了一些背景上下文。我根据自己理解的内容执行了以下操作。但我不确定这是否是一个正确的解决办法。我的想法是--如果我进入背景,它不能影响主线。

//I have an PersistentContainer created by Xcode.

//I create an backgroundContext.
self.backContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.newBackgroundContext()

//Then if the user adds a new record, it's added to backContext and saved to mainContext
...
let newRecord = Record(context: self.backContext!)
...
self.backContext!.save()
self.context!.save() // mainContext
...

//If the user fetches the data I use:
self.backContext.perform {
...
}

//Since I want to show results in UI, I know these objects (from fetch) exist just in the background thread, so instead I fetch for IDs 
.resultType = .managedObjectIDResultType

//Now I have IDs of fetched objects, so I restore objects in main thread using their IDs:
let object = try? self.backContext.existingObject(with: ID) as? Record

//and I can finally use fetched objects to update UI.

问题是:

  • 我现在做的事情对吗?(它工作得很好)
  • 这会解决用户获取大量数据时冻结UI的问题吗?

我们如何正确使用backgroundContexts?为什么不建议直接使用MainContext?如何防止在取大数据的同时冻结UI?

还有一个问题:如果我使用FetchedResultsConteroller-我需要处理冻结UI的问题吗?(在等待第一个(init)提取结果时?)

当然,我忽略了在获取数据时,我的上下文被阻塞,因此我无法创建新记录

共有1个答案

濮阳钟展
2023-03-14

如果您正在获取要显示在屏幕上的对象,那么您绝对应该针对主线程上下文使用fetch请求。核心数据是为这个特定的用例而设计的,您不应该因为执行取数而经历速度减慢或冻结。如果你遇到了问题,那么在instruments中分析你的应用程序,找出实际的减速在哪里。

如果您正在执行大量或长时间运行的工作,例如处理大型API响应,您已经证明这会影响主线程的性能,则需要使用背景上下文。

 类似资料:
  • CoreData-CustomObject 能让用户学会使用 CustomObject 创建和加载数据。

  • 将 coredata 数据存储到SQLite数据库中,并从数据库中读取数据。 [Code4App.com]

  • TLDR版本:我的应用程序如何知道设备a上的CoreData对象、设备B上的CoreData对象和CloudKit中的CKRecord都是相同的记录? 详细版本: 我正在开发一个应用程序,它在本地使用CoreData和CloudKit来实现设备间的同步。我不明白添加多个设备后,CoreData关系和CloudKit引用应该如何协同工作。 2)当您创建CloudKit记录时,您可以为它分配一个记录名

  • 问题内容: 我当前正在使用Xcode 6 beta 7,并在创建项目后决定需要CoreData。我已经看过一些已经问到目标C的问题,同时还观看了有关该主题的视频,但我似乎遇到了同样的错误。至于我对CoreData框架本身的用法,我很确定它是正确的,因为我创建了另一个空项目(选中了CoreData框),并且遵循相同的实现,它像一个魅力一样起作用,但是我可能有问题也在那里做。因此,这是我在Swift的

  • 问题内容: 我想在CoreData中存储托管对象的枚举状态 最后一步是将StateFullManagedObject的状态变量转换为ObjStatus以进行直接比较,这对我不起作用。例如,我不能在Int16和Int16枚举之间使用==运算符。我得到的编译时错误是 Int16不能转换为’MirrorDisposition’ 。请参阅以下条件: 如何在Int16和枚举之间进行比较/分配? 问题答案:

  • 问题内容: 在我的tableViewController中,我有以下内容。我正在尝试删除一个项目。 然后尝试删除我有。 问题答案: 通过在swift和coredata中执行数据删除来更新我的编码问题。这最终使我的代码起作用了。 上面针对Swift 2.2和Xcode 7.3.1的编辑 还需要对这两行代码进行更正。