2

NSURLSessionNSURLSessionTask を作成して再開した後、操作キューが空になるのはなぜですか?

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];
4

2 に答える 2

10

提案された を使用して、セッションの無効化を回避する解決策を見つけましたDispatchGroup

(答えはSwiftにありますが、質問はObjCにあります...しかし、それは同じロジックです)

を使用する場合は、 anduploadTaskWithStreamedRequest:を実装する必要があることに注意してください。したがって、答えを簡単にするために、withの使用を示します。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
    }
}
于 2016-12-13T12:04:44.080 に答える
1

セッションの再利用を気にせず、非同期で行うことを気にしない限り、非常に簡単です。

  • セッションを呼び出しfinishTasksAndInvalidateます。
  • セッション デリゲートにメソッドを実装してURLSession:didBecomeInvalidWithError:、最後のタスクが完了した後に必要な作業を行います。

とはいえ、上記のコードの問題は、コードが実行ループをブロックしている限り、最初のフェッチを開始するまでセッションに操作がないことです。通常、NSURLSession を同期的に使用しようとしないでください。ほとんどの場合、物事を解決する方法は間違っています。:-)

于 2016-12-03T20:24:03.207 に答える