回调运行的队列是什么?

时间:2017-08-23 22:10:15

标签: swift grand-central-dispatch

我使用串行DispatchQueue来读取一组PHAssets并将它们逐个上传到远程主机。

代码使用PHAsset.fetchAssets(),然后在enumerateObjects中,我使用queue.async { .. }将任务添加到队列中。在任务中,我使用PHImageManager.default().requestImageData,它读取资产的内容并通过执行闭包将其返回为Data

因此,在每个排队任务中结束的代码如下所示:

self.queue.async {
  PHImageManager.default().requestImageData(
    for: asset,
    options: self.imageRequestOptions()) { (data: Data?, dataUTI: String?, orientation: UIImageOrientation, info: [AnyHashable : Any]?) in

        print( "--> Upload data: \(data?.description ?? "n/a")" )
        usleep( 2000000 )

    }
}

我的队列定义如下:

let queue = DispatchQueue(
  label: "com.myapp.asset_upload_queue",
  qos: .background
)

我遇到的问题PHImageManager.requestImageData立即返回,因此下一个任务会立即开始读取数据。最终结果是我最终得到了多个并发上传,并且CPU一直在屋顶上射击。

我认为问题是回调PHImageManager.requestImageData采取的是不阻止队列线程,因此它继续进行下一个任务。下一个任务立即开始读取数据。

我尝试将回调中的内容放入队列中,如:

self.queue.async {
  PHImageManager.default().requestImageData(
    for: asset,
    options: self.imageRequestOptions()) { (data: Data?, dataUTI: String?, orientation: UIImageOrientation, info: [AnyHashable : Any]?) in

        self.queue.async {
          print( "--> Upload data: \(data?.description ?? "n/a")" )
          usleep( 2000000 )
        }

    }
}

这开始按顺序执行上传,但requestImageData调用仍在一个接一个地执行,这给CPU带来了巨大的压力。

问题:

我如何控制流量,以便只有在上一次上传完成后才会执行requestImageData

我尝试过的其他事情

我的第一个方法是尝试get an asset path directly from the Photos framework,据说可以使用requestContentEditingInputWithOptions来完成。但是,我只能在模拟器上工作而不能在任何真实设备上工作。

1 个答案:

答案 0 :(得分:2)

您可以尝试信号量:在队列调用之前创建它,在队列调用之后在信号量上添加等待,并在队列执行内的代码末尾发出信号量信号。