【问题标题】:How to merge changes between core data background context and main context in Swift如何在 Swift 中合并核心数据背景上下文和主上下文之间的更改
【发布时间】:2021-04-11 20:35:36
【问题描述】:

我有一个将数据从 CSV 导入核心数据的 MacOS 应用程序。由于这可能是一个长时间运行的过程,我选择在后台线程中进行导入,这样我就可以使用导入进度更新 UI。因此,为了避免在将更改保存到持久存储时出现乐观锁定失败,我在后台上下文和主上下文之间合并了保存时的更改。

我认为我没有正确处理合并更改,因为当我在后台上下文中调用 save 时,它​​会调用一个阻塞 UI 的合并更改函数。有没有办法在不阻塞 UI 的情况下合并上下文之间的更改?

以下是我创建称为 moc2 的背景上下文的方法:

let app = NSApplication.shared.delegate as! AppDelegate
let container = app.persistentContainer
        container.performBackgroundTask(){ (moc2) in
NotificationCenter.default.addObserver(self.app, selector: #selector(self.app.handleBackgroundCoreDataChangeInMainManagedContext(notification:)), name: NSNotification.Name.NSManagedObjectContextDidSave, object: moc2)
//perform import...
self.save(moc2: moc2)
}

还有保存功能:

func save(moc2: NSManagedObjectContext){
    do {
        try moc2.save()
    } catch {
        print(error)
    }
}

这是 AppDelegate 中的合并更改选择器:

@objc func handleBackgroundCoreDataChangeInMainManagedContext(notification: Notification){
    DispatchQueue.main.async {
        self.managedObjectContext?.mergeChanges(fromContextDidSave: notification)
    }
}

有没有办法使用 DispatchQueue.main.async 在不阻塞 UI 的情况下合并更改?

【问题讨论】:

    标签: swift macos cocoa core-data


    【解决方案1】:

    我在 AppDelegate 中测试了一个从通知对象获取上下文的新函数,然后在该上下文的线程上异步执行 mergeChanges。这至少不会阻塞用户界面。在未来的一些测试之后,我会看看更改是否仍然存在。

    @objc func handleBackgroundCoreDataChangeInMainManagedContext(notification: Notification){
        if let moc2 = notification.object as? NSManagedObjectContext {
            moc2.perform {
                moc2.mergeChanges(fromContextDidSave: notification)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2019-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多