NSURLSessionを使用して多数のファイルをダウンロードする必要があるユースケースがあります。非同期タスクの内部停止時にRunloopを使用する
セッション・タスクのタイムアウトを維持するには、それらを操作キューに配置し、同時ダウンロードの量を制限して飢えないようにする必要があります。
私の考えは、タスクの再開をnsoperationにロードして、それをnsoperationqueueにロードすることで、同時にアクティブになる回数を制限します。
問題は、[タスクの再開]を呼び出すとコードが終了し、ファイルのダウンロードが完了するのを待っていても動作が完了したとみなされるという問題です。
ここにいくつかのコードがあります。
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest: request
completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
//move the file to a permanent location
CFRunLoopStop(CFRunLoopGetCurrent());
}
//I have instantiated a class global NSOperation queue.
[imageDownloadQueue addOperationWithBlock:^void() {
[task resume];
CFRunLoopRun();
}];
コールバックを待機している間、どのようにして停止スレッドを有効にしておくことができますか?また、NSMachPortにnsrunloopを使ってポートを追加しようとしました。それは助けに見えなかった。
また、タスクを再開するとタイムアウトタイマーが開始されるため、NSURLSessionでHttpMaximumConnectionsPerHostを設定しても問題ありません。これは私が以前よりもタイムアウトを増やすことを意味します。
この種の問題については、https://developer.apple.com/videos/play/wwdc2015/226/(WWDC 2015 Advanced NSOperations)を参照してください。一年後、私はDave DeLongに、彼がまだ働いていると思っているかどうかを知るために、このパターンについて挑戦しました。彼はそれが非常に成功し続けていると言います。 –
それは良いビデオでしたが、パターンを書き換える時間がありません。それは、これより多くのコードです。私は、スレッドが生き続ける方法と、コールバックが自分自身を取り除く方法を欲しがっています。 – mac10688
これは非同期NSOperationsのためのものです。カスタム 'NSOperation'を行い、' isAsynchronous'に対して 'true'を返し、' main() 'ではなく' start() 'をオーバーライドします。適切な時刻に(つまり、操作が完了したとき) 'isExecuting'と' isFinished'を手動で設定する必要があります。あなたは「スレッドが生き続ける」ことを望んでいません。あなたは、操作が正しい時刻に完了するようにしたい。これが非同期操作の仕組みです。つまり、main()が戻るときに、あなたが手で行うことを意味します。 –