【发布时间】:2018-03-30 14:34:33
【问题描述】:
最近在看流行的图片缓存库Kingfisher的代码。
我对@987654324@ 上的 GCD 用法感到困惑。在那个下载器中,所有与ImageFetchLoad(获取图像的任务)相关的操作都被分派到一个名为barrierQueue的并发队列中:
barrierQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Barrier.\(name)", attributes: .concurrent)
令人困惑的部分是所有操作都是使用屏障同步调度的:
barrierQueue.sync(flags: .barrier) {
if let URL = task.internalTask.originalRequest?.url, let imageFetchLoad = self.fetchLoads[URL] {
imageFetchLoad.downloadTaskCount -= 1
if imageFetchLoad.downloadTaskCount == 0 {
task.internalTask.cancel()
}
}
}
每个屏障操作都会相互阻塞,这使得队列实际上是一个串行的。因此,为什么 Kingfisher 使用 concurrent 队列而不是 serial 队列?
【问题讨论】:
-
当它可能只是历史时,不要认为有深层原因。您是否联系过添加标志的开发人员? (onevcat: github.com/onevcat/Kingfisher/commit/…) 特别注意,在那次提交之前,有些使用了
.barrier,有些没有:github.com/onevcat/Kingfisher/blob/… -
根据我的理解障碍在并发队列中是有意义的,不确定在串行队列中是否有意义,因为无论如何任务都会一个接一个地执行。
标签: ios swift multithreading grand-central-dispatch kingfisher