回调在哪个队列上运行?



我正在使用串行调度队列来读取一组PHAsset并将它们逐个上传到远程主机。

该代码使用 PHAsset.fetchAssets((,然后在枚举对象中,我使用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

我尝试过的其他事情

我的第一个方法是尝试直接从 Photos 框架获取资产路径,据报道这可以通过使用requestContentEditingInputWithOptions来完成。但是,我只能在模拟器上使用它,而不是在任何真实设备上工作。

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

相关内容

  • 没有找到相关文章

最新更新