簡體   English   中英

在訪問核心數據模型之前,如何確保已進行所有網絡調用?

[英]How do I ensure that all network calls have been made before accessing my core data model?

我連續進行多個api調用,當我最終推送到下一個視圖控制器時,我的數據與核心數據模型完全空白。 ViewController A我按此順序發出了以下請求:

Api.verifyOtp(email, otp).continueWith { (task) -> Any? in
            if task.succeed {

                self.apiCallOne()
                self.apiCallTwo()
                self.apiCallThree()
                self.apiCallFour()
                self.apiCallFive()

            } else {
                Hud.hide()
                task.showError()
            }
            return nil
        }

現在,所有這些調用都是異步進行的。 但是,最后一個方法self.apiCallFive()是推送到ViewController B的方法。 這里是電話:

Api.apiCallFive().continueOnSuccessWith { (task) -> Any? in
        Hud.hide()
        if task.succeed {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let viewB storyboard.instantiateViewController(withIdentifier: "ViewControllerB"                        self.navigationController?.pushViewController(viewB, animated: true)
        }

我的猜測是,由於所有這些請求都是異步發生的,因此無法保證哪個調用將首先完成。 因此, apiCallFive()正在推入並加載ViewController B,然后其他人才能完成。 我如何才能使下一個視圖在所有任務完成之前不會被加載或推入?

謝謝!

我也遇到過同樣的問題。 通過使用DispatchGroup對其進行修復。

碼:

定義為property

let APIGroup = DispatchGroup()

當任何API調用開始時,執行以下代碼。

APIGroup.enter()

當任何API調用完成時,執行以下代碼。

downloadGroup.leave()

通知塊:

APIGroup.notify(queue: DispatchQueue.main) {
    print("All APIs called successfully: Perform required operation")
}

無需通過任何計數器或其他變量進行管理。 當所有任務成功完成時,自動notify塊調用。

這里真正重要的是回車休假對。 您必須非常小心,並確保離開小組。 在上面的代碼中引入錯誤很容易。 假設在返回之前,我們並未在上述保護聲明中離開該組。 如果調用的API失敗,或者JSON格式錯誤,則組數>條目數將與葉子數不匹配。 因此,組完成處理程序將永遠不會被調用。 如果您正在從UI調用此方法並在運行網絡請求時顯示活動指示器,則您將永遠不會從該方法獲得回調,並且將繼續旋轉🙂

蘋果文件

為了解決這個問題,您需要一種在每次通話結束時得到通知的方式。 最簡單的方法是在每個調用中使用完成塊。

func apiCall(completion: @escaping () -> Void) {
    ....
}

將完成代碼塊添加到api調用后,您的代碼塊可能如下所示:

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()
apiCallOne {
    dispatchGroup.leave()
}

dispatchGroup.enter()
apiCallTwo {
    dispatchGroup.leave()
}

...


dispatchGroup.enter()
apiCallN {
    dispatchGroup.leave()
}
dispatchGroup.wait(timeout: Constants.timeout)

請記住, wait語句將阻塞您調用它的線程,直到執行所有leave()語句為止,因此請注意不要以死鎖結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM