如何确保在Grand Central Dispatch中一个功能接一个运行?

时间:2019-06-24 02:00:09

标签: swift xcode grand-central-dispatch dispatch

基本上,我想先运行一些图像,然后再运行其他依赖于要上载图像的功能。我想我可能对GCD是什么/线程如何工作有误解。我希望功能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在上传图片完成之前一直保持运行状态,因为它们花费的时间要少得多。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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