核心数据:后台 NSManagedObjectContext 更新在保存时不起作用

Core Data: Update on background NSManagedObjectContext not working upon save

我有两个托管对象上下文,我想按照通常的建议将每个上下文用于 fetchupdate

但是,我所有试图利用 newBackgroundContext() 保存数据的尝试都失败了。 performBackgroundTask 也没有用。

我使用viewcontext保存成功(下面的代码是成功的),但是它违背了后台保存功能的目的。另外,它可能会导致未来表现不佳。

我已经尝试在我的两个上下文中设置 automaticallyMergesChangesFromParent = true,但无济于事。

CoreDataManager 在我下面的代码中是一个样板 class 设置惰性变量返回 persistentContainercontext 对象。

是否有适当的方法指示任何地方如何处理这个标准问题?

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)")
    }
}

If I use newBackgroundContext() for fetch and save both (just in the below function, not in my UI), it works too. But I do not know if this is recommended approach

是的,这是正确的做法。

当您在某些上下文中初始化数据时,您必须将其保存在同一上下文中。如果您尝试保存另一个上下文,它将不起作用,因为这个其他上下文没有更改。

当您使用一个上下文获取一些数据时:

let result = try context.fetch(fetchRequest)

然后你修改它:

myModel.data = data

仅在此上下文中可见。这意味着如果您尝试保存另一个上下文,它不会看到对模型的更改,您的数据也不会被保存。