如何保证 Grand Central Dispatch 中一个函数接一个运行?

How to guarantee one function runs after another in the Grand Central Dispatch?

基本上,我想在 运行 依赖于正在上传的图像的其他功能之前上传一些图像。我想我可能误解了 GCD is/how 线程的工作原理。我希望功能 1 和 2 在我上传图像后发生。它们都可以快速执行,但严重依赖上传图像来完成。也许我不应该使用 GCD(因为我想实现一个等待指示器)?我似乎无法正确执行它

        if goToHome {
            DispatchQueue.global().async {
                DispatchQueue.main.sync {
                    self.uploadImages() // Uploads the images, takes a good amount of time to execute
                    function1()
                    function2()


                }
            }

函数 1 和 2 在上传图像完成之前保持 运行ning,因为它们执行时间要少得多。

尽管运行主队列中的上传图片功能,上传图片功能本身是运行后台队列中的操作。要解决此问题,可能的策略是:

  • 使用图像上传完成处理程序,可能最容易实现,具体取决于 self.uploadImages() 函数的实现
  • 让图片上传发生在主线程,这可能很难实现并且不可取
  • 使用调度组,我个人对此经验较少,但可以选择

Swift中的基本模式是在后台线程做上传等工作,然后在主线程调用完成函数并根据上传是否成功继续工作。

通常,如果您需要对用户界面执行某些操作,例如设置进度指示器(必须在主线程上进行),您会回调到主线程。

所以像这样:

func uploadInBackground(_ images: [Image], completion: @escaping (_ success: Bool) -> Void) {
    DispatchQueue.global(qos: .background).async {
        var success = true

        // upload the images but stop on any error
        for image in images {
            success = uploadImage(image) // upload your images somehow

            guard success else { break }
        }

        DispatchQueue.main.async {
            completion(success)
        }
   }
}

func mainThreadUploader() {
    let images = [Image(), Image()] // get your images from somewhere

    // we are on the main thread where UI operations are ok, so:
    startProgressIndicator()

    uploadInBackground(images) { success in
        // this callback is called on the main thread, so:
        stopProgressIndicator()

        guard success else { return }

        // images uploaded ok, so proceed with functions that depend on
        // the upload(s) completing successfully:
        function1()
        function2()
    }
}