如何等待NSURLSession的所有任务完成?
创建并恢复NSURLSessionTask后,为什么NSURLSession
操作队列为空?如何等待NSURLSession的所有任务完成?
有没有办法判断NSURLSession是否有待处理的任务?
目标是等待多个任务来完成,但是这并不工作:
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithStreamedRequest:request];
[uploadTask resume];
// this prints "0"
NSLog(self.session.delegateQueue.operationCount)
// this returns immediately instead of waiting for task to complete
[self.session.delegateQueue waitUntilAllOperationsAreFinished];
我找到了一个避免使会话失效的解决方案,使用建议的DispatchGroup
。
(答案是斯威夫特,而问题是ObjC ...但它是相同的逻辑)
需要注意的是,使用时uploadTaskWithStreamedRequest:
,我们需要实现一个URLSessionTaskDelegate
和func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
。所以,为了简化答案,我将演示DispatchGroup
与uploadTaskWithRequest:from:completionHandler:
的用法。
// strong reference to the dispatch group
let dispatchGroup = DispatchGroup()
func performManyThings() {
for _ in 1...3 {
let request = URLRequest(url: URL(string: "http://example.com")!)
dispatchGroup.enter()
let uploadTask = self.session.uploadTask(with: request, from: nil) { [weak self] _, _, _ in
self?.dispatchGroup.leave()
}
uploadTask.resume()
}
dispatchGroup.notify(queue: .main) {
// here, all the tasks are completed
}
}
这很容易,只要你不关心重用会话,不介意做异步事情:
- 呼叫
finishTasksAndInvalidate
在会话上。 - 在会话委托中实现
URLSession:didBecomeInvalidWithError:
方法,以完成上一个任务完成后需要执行的任何工作。
这就是说,上面的代码的问题是,会话没有任何操作,直到它开始第一次获取,只要您的代码阻止运行循环,这不会发生。您通常不应该尝试同步使用NSURLSession。这几乎总是解决问题的错误方法。 :-)
我已经提出了你的答案,因为我没有指定重用会话。真相是,我需要重用它,所以我接受了不同的答案。 –
OK,我可能已经发现,在https://github.com/AFNetworking/AFNetworking/issues/1504线索和https://stackoverflow.com/q/19414486/1033581有关事实'NSURLSession '不能单独用于配料。 –
DispatchGroup是你需要的:)发现这个非常谷歌的结果链接http://commandshift.co.uk/blog/2014/03/19/using-dispatch-groups-to-wait-for-multiple-web-services/ –