【发布时间】:2017-08-23 22:10:15
【问题描述】:
我正在使用串行 DispatchQueue 读取一组 PHAsset 并将它们一个一个上传到远程主机。
代码使用 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.requestImageDatatakes 不会阻塞队列线程,因此它会继续执行下一个任务。下一个任务立即开始读取数据。
我尝试将回调中的内容放入队列中,如下所示:
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 来完成。但是,我只能让它在模拟器上运行,而不能在任何真实设备上运行。
【问题讨论】:
标签: swift grand-central-dispatch