Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 使用核心数据保存多个异步上下文,数据丢失_Swift_Asynchronous_Core Data - Fatal编程技术网

Swift 使用核心数据保存多个异步上下文,数据丢失

Swift 使用核心数据保存多个异步上下文,数据丢失,swift,asynchronous,core-data,Swift,Asynchronous,Core Data,当应用程序启动时,我想更新我的当前数据库。有时并非所有的数据都被保存,一些数据丢失 我正在使用此功能进行保存: func save1() { let group = DispatchGroup() for a in save.oldVersion.defaExchangesEinzeln { if save.checkForVersionExchange(exchange: a.key) { group.e

当应用程序启动时,我想更新我的当前数据库。有时并非所有的数据都被保存,一些数据丢失

我正在使用此功能进行保存:

func save1() {
        let group = DispatchGroup()

        for a in save.oldVersion.defaExchangesEinzeln {
            if save.checkForVersionExchange(exchange: a.key) {
                group.enter()
                save.saveVersionExchanges(exchange: a.key)
                save.storeContainer.performBackgroundTask{ context in
                    self.save.saveDefAExchange(managedContext: context, exchange: a.key)
                    try? context.save()
                    group.leave()
                }
            }
        }
        for b in save.oldVersion.fdefCoinstBtc {
            if save.checkForVersionFdefCoinsTBTC(exchange: b.key) {
                save.saveVersionFdefCoinsTBTC(exchange: b.key)
            }
        }

        for c in save.oldVersion.fdefCoinstUsd {
            if save.checkForVersionFdefCoinsTUSD(exchange: c.key) {
                save.saveVersionFdefCoinsTUSD(exchange: c.key)
            }
        }

        if save.checkForCoinNamesExall() || save.checkForVersionIconsExall() || save.checkForVersionFdefCoinsTarrExall() {
            save.saveVersionOthers()
        }

        if save.checkForCoinNamesExall() {
            group.enter()
            storeContainer?.performBackgroundTask{ context in
                self.save.saveCoinNames(managedContext: context)
                do {
                    try context.save()
                } catch let error {
                    print(error.localizedDescription)
                }
                group.leave()
            }
        }
        if save.checkForVersionIconsExall() {
            group.enter()
            storeContainer?.performBackgroundTask { context in
                self.save.saveIcons(managedContext: context)
                do {
                    try context.save()
                } catch let error {
                    print(error.localizedDescription)
                }
                group.leave()
            }
        }

        if save.checkForVersionFdefCoinsTarrExall() {
            group.enter()
            storeContainer?.performBackgroundTask { context in
                self.save.saveGroups(context)
                do {
                    try context.save()
                } catch let error {
                    print(error.localizedDescription)
                }
                group.leave()
            }
        }
        group.notify(queue: .main) {
            print("Update complete 1")
            self.delegateWebsocket?.startWebsocket()
        }
    }
我可以想象,由于异步调用,上下文之间会发生冲突。 为什么会这样?如何改进代码? 谢谢

使用performBackgroundTask非常方便,但它有一个最初并不总是明显的优势。每次调用performBackgroundTask时,都会创建一个新的上下文,并且传入的块在该上下文的专用队列上执行。块是异步执行的

结果是,如果您在循环中重复调用performBackgroundTask,就无法保证这些块会相对彼此同步。这可能是个问题

有几种方法可以解决这个问题。我不确定我是否遵循了您的所有代码,所以我不确定哪种可能是最好的。备选方案包括:

将所有代码包装在一个performBackgroundTask中,而不是创建一堆后台任务。或者可能只是通过将performBackgroundTask置于初始循环之外而不是内部来减少任务数量。 放下performBackgroundTask。相反,创建一个单一的背景上下文并使用它。使用newBackgroundContext获取一个新的上下文并保持它。然后用该上下文上的perform或performAndWait调用替换上面的后台任务。
谢谢,我将所有代码打包在一个PerformBackground任务中。