2016-11-30 84 views
1

創建並恢復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]; 
+0

OK,我可能已經發現,在https://github.com/AFNetworking/AFNetworking/issues/1504線索和https://stackoverflow.com/q/19414486/1033581有關事實'NSURLSession '不能單獨用於配料。 –

+1

DispatchGroup是你需要的:)發現這個非常谷歌的結果鏈接http://commandshift.co.uk/blog/2014/03/19/using-dispatch-groups-to-wait-for-multiple-web-services/ –

回答

3

我找到了一個避免使會話失效的解決方案,使用建議的DispatchGroup

(答案是斯威夫特,而問題是ObjC ...但它是相同的邏輯)

需要注意的是,使用時uploadTaskWithStreamedRequest:,我們需要實現一個URLSessionTaskDelegatefunc urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)。所以,爲了簡化答案,我將演示DispatchGroupuploadTaskWithRequest: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 
    } 
} 
1

這很容易,只要你不關心重用會話,不介意做異步事情:

  • 呼叫finishTasksAndInvalidate在會話上。
  • 在會話委託中實現URLSession:didBecomeInvalidWithError:方法,以完成上一個任務完成後需要執行的任何工作。

這就是說,上面的代碼的問題是,會話沒有任何操作,直到它開始第一次獲取,只要您的代碼阻止運行循環,這不會發生。您通常不應該嘗試同步使用NSURLSession。這幾乎總是解決問題的錯誤方法。 :-)

+0

我已經提出了你的答案,因爲我沒有指定重用會話。真相是,我需要重用它,所以我接受了不同的答案。 –