如何等待NSURLSession的所有任务完成?

Cœu*_*œur 2 nsoperationqueue ios nsurlsession nsurlsessiontask

为什么NSURLSession在创建和恢复NSURLSessionTask后操作队列为空?

有没有办法判断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];
Run Code Online (Sandbox Code Playgroud)

Cœu*_*œur 7

我找到了一个解决方案,使用建议的方法避免会话无效DispatchGroup.

(答案在Swift中,而问题在于ObjC ......但它是相同的逻辑)

注意,在使用时uploadTaskWithStreamedRequest:,我们需要实现一个URLSessionTaskDelegatefunc urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?).所以,为了简化答案,我将演示使用DispatchGroupwith 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
    }
}
Run Code Online (Sandbox Code Playgroud)