CoreData 是不是可以在另一个上下文/后台任务中从一个上下文/线程安全地使用 NSManagedObject

Posted

技术标签:

【中文标题】CoreData 是不是可以在另一个上下文/后台任务中从一个上下文/线程安全地使用 NSManagedObject【英文标题】:CoreData is it possible to safely use NSManagedObject from one context/thread in another context/background taskCoreData 是否可以在另一个上下文/后台任务中从一个上下文/线程安全地使用 NSManagedObject 【发布时间】:2019-12-09 20:27:18 【问题描述】:

是否可以在不同的后台任务之间使用 NSManagedObjects? 我有这样的代码,当执行时使用 load() 方法在一个上下文/后台任务上使用 .performBackgroundTask context

加载 NSManagedObjects

然后我想执行另一个 .performBackgroundTask context 但问题是 NSManagedObject 似乎不可用,因为所有属性都从 .performBackgroundTask 停止返回字段

 self.load(predicate: NSPredicate(format: "company.id = %@", companyId))
            .flatMap  contacts in

                Future  promise in

                    self.storage.persistentContainer.performBackgroundTask  context in

                        let request : NSFetchRequest<Company> = Company.fetchRequest()
                        request.predicate = NSPredicate(format: "id = %@", companyId)

                        let result = try? context.fetch(request)

【问题讨论】:

【参考方案1】:

我建议您阅读Core Data concurrency overview 以了解基础知识。 不管您有什么问题... 您不能直接在上下文/线程之间传递托管对象。 您可以做的是从一个上下文传递objectIDs 关闭对象,并使用它们从另一个上下文/线程中获取对象。 就性能而言,如果有很多对象,这可能不是一个好主意,我建议您使用单个上下文在一个 performBackgroundTask 中获取合同和公司。如果您不想公开其逻辑,可以将上下文作为参数传递给 load 函数。

【讨论】:

好吧,我走这条路,只是在每个方法中重复获取逻辑,而不是重复使用它。也许我可以使用一个私有上下文而不是 performBackgroundTask 来改进我的 Dao,但是这种重复并没有那么长和糟糕。在 UI 上,我使用 SwiftUI 的 FetchRequest 现在它似乎工作得更好。 您可以创建一个将上下文作为参数并返回结果数组的方法,而不是复制获取。很高兴我能帮忙:)

以上是关于CoreData 是不是可以在另一个上下文/后台任务中从一个上下文/线程安全地使用 NSManagedObject的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 3 托管对象上下文

当应用程序处于后台时,从推送通知中插入 coredata 记录

CoreData 和 NSManagedObject 上下文 - 私有与主

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

Swift 3.0 CoreData 创建多上下文

核心数据:在后台将一批记录写入磁盘