【发布时间】:2017-01-30 08:20:46
【问题描述】:
我想创建一个简单的下载队列,我不需要太多功能,只需要一个串行队列,这样当我运行我的下载过程时,它只会等待第一次下载完成,然后再开始第二次下载。我正在使用 parse-server,它无论如何都会在后台运行其查询和获取数据功能,但它似乎同时运行。
我正在考虑只使用 GCD,因为当解析服务器功能正在处理这个问题时,我没有直接看到需要使用创建 NSURL 会话来下载我的文件。
为此我定义了一个队列:
let downloadQueue = DispatchQueue(label: "downloadQueue", qos: .background)
然后认为将我的下载功能包装在这个队列中会将要下载的项目添加到队列的后面。但是,这似乎没有发生,文件一被选中就会开始下载。
func downloadDataToDevice(cell: JourneyCollectionViewCell, selectedIndexPath: IndexPath){
self.downloadQueue.async {
// query and progressBlock to track download progress
}
}
【问题讨论】:
-
你在
cellForRow中打电话给downloadDataToDevice吗? -
self.downloadQueue.sync也许? -
我也试过了。一样。这可能与 parse 如何运行它的查询有关,但我认为 GCD 不会在 block util 中运行代码,因为其他任务已完成。
-
问题在于分派的代码本身是异步的。理论上,您可以使用信号量使调度的块等待异步调用(在进程中占用一个线程),或者更好地使用
OperationQueue而不是自定义异步Operation子类。它还为使用maxConcurrentOperationCount控制并发程度打开了大门(因为按顺序下载会遭受惊人的性能损失)。 -
更激进的做法是,如果下载大型资产,请在后台
URLSession进行下载,这样您就可以完全脱离调度队列或操作队列,URLSession将管理这些资源你,即使在你的应用程序终止后,这在进行大量下载时非常有用。当用户可以离开并使用他们的设备做更有成效的事情时,为什么还要坐在那里盯着一个正在下载的应用程序。 (如果在 iOS 中这样做,这尤其有用。)
标签: swift asynchronous grand-central-dispatch