首页 > 解决方案 > Swift:告诉回调在全局队列上运行

问题描述

我正在运行后台上传任务,但我发现它阻塞了主线程。看了之后我怀疑这是因为第 3 方库(在这种情况下为 Firebase)必须在主线程上安排其异步回调。

有没有办法显式地让回调在全局线程上运行?

这是我从主线程启动任务的方式:

DispatchQueue.global(qos: .background).async {
  PhotoUploadOperation().start()
}

这是上传任务的简化版本:

class PhotoUploadOperation {
  func uploadCameraRoll() {
    for element in photos {
      self.uploadPhoto(element.image, uid) { url in
        // Some work

        if let url = url {
          let photo = Photo(uid: uid, url: url, creationDate: element.date)
          self.sendPhoto(photo: photo) { success in
            // Some work
          }
        }
      }
    }
  }
}

标签: swiftconcurrencyio

解决方案


你能试试这个解决方案吗?

Firebase 或其他 3party 框架使用“方法转换”来完成一些网络日志或其他事情。但是你的情况有点不同。

extension DispatchQueue {
    
        static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {
            DispatchQueue.global(qos: .background).async {
                background?()
                if let completion = completion {
                    DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
                        completion()
                    })
                }
            }
        }
    }

用法:

DispatchQueue.background(delay: 3.0, background: {
    // do something in background
}, completion: {
    // when background job finishes, wait 3 seconds and do something in main thread
})

DispatchQueue.background(background: {
    // do something in background
}, completion:{
    // when background job finished, do something in main thread
})

DispatchQueue.background(delay: 3.0, completion:{
    // do something in main thread after 3 seconds
})

而且您不要忘记允许来自签名和功能的后台处理 在此处输入图像描述


推荐阅读