核心数据:后台更新 NSManagedObjectContext 在保存时不起作用
Posted
技术标签:
【中文标题】核心数据:后台更新 NSManagedObjectContext 在保存时不起作用【英文标题】:Core Data: Update on background NSManagedObjectContext not working upon save 【发布时间】:2020-06-14 21:56:15 【问题描述】:我有两个托管对象上下文,我想按照通常的建议将每个用于 fetch
和 update
。
但是,我使用newBackgroundContext()
保存数据的所有尝试都失败了。 performBackgroundTask
也没有工作。
我使用viewcontext
成功保存(下面的代码是成功的),但它违背了具有后台保存功能的目的。另外,这可能会导致未来的表现不佳。
我已经尝试在我的两个上下文中设置automaticallyMergesChangesFromParent = true
,但无济于事。
我下面的代码中的CoreDataManager
是一个样板类,用于设置返回persistentContainer
和context
对象的惰性变量。
是否有适当的方法在任何地方指出如何处理这个标准问题?
PS:当我尝试使用 newBackgroundContext()
插入大量对象时,它工作正常。更新是唯一的问题——可能是因为它涉及到由viewContext
处理的获取。
PS+: 就此而言,如果我使用newBackgroundContext()
获取并保存两者(仅在下面的函数中,而不是在我的 UI 中),它也可以工作。但我不知道这是否是推荐的方法。
PS++:我还尝试将 newBackgroundContext()
包装在一个惰性 var 下,以免每次都创建一个新的,无论如何都会在 performBackgroundTask
内部发生 - 但这种方法仍然无法保存成功。
class func updateRecord(recordId: String, data: Data)
let fetchRequest = NSFetchRequest<MyModel>(entityName: "MyModel")
let context = CoreDataManager.sharedInstance.queryContext //wrapper for persistentContainer.viewContext which is used to fetch the intended object to update
do
fetchRequest.predicate = NSPredicate(format: "recordId == %@", recordId)
let result = try context.fetch(fetchRequest)
guard let myModel = result.first
else
throw CoreDataCustomError.ObjectNotFound
myModel.data = data
try context.save() //works FINE!
//what DOES NOT work: try persistentContainer.newBackgroundContext().save()
//what DOES NOT work:
//persistentContainer.performBackgroundTask (context) in
// context.save()
//
catch let customErr as CoreDataCustomError
print("Object does not exist in DB: \(customErr)")
catch let err
print("Error saving data \(recordId): \(err)")
【问题讨论】:
【参考方案1】:如果我使用 newBackgroundContext() 来获取并保存两者(就在 下面的功能,不在我的 UI 中),它也可以工作。但我不知道这是否 是推荐的方法
是的,这是正确的方法。
当您在某些上下文中初始化数据时,您必须将其保存在同一上下文中。如果您尝试保存另一个上下文,它将无法正常工作,因为这个其他上下文没有任何更改。
当您使用一个上下文获取一些数据时:
let result = try context.fetch(fetchRequest)
然后你修改它:
myModel.data = data
它仅在此上下文中可见。这意味着如果您尝试保存另一个上下文,它将不会看到模型的更改,并且您的数据也不会被保存。
【讨论】:
以上是关于核心数据:后台更新 NSManagedObjectContext 在保存时不起作用的主要内容,如果未能解决你的问题,请参考以下文章
核心数据 NSManagedObject - ObservedObjects 未更新
当更新版本已经在内存中时,强制核心数据从以前存储的版本刷新 NSManagedObject