2016-09-22 5 views
0

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を設定しても問題ありません。これは私が以前よりもタイムアウトを増やすことを意味します。

+1

この種の問題については、https://developer.apple.com/videos/play/wwdc2015/226/(WWDC 2015 Advanced NSOperations)を参照してください。一年後、私はDave DeLongに、彼がまだ働いていると思っているかどうかを知るために、このパターンについて挑戦しました。彼はそれが非常に成功し続けていると言います。 –

+0

それは良いビデオでしたが、パターンを書き換える時間がありません。それは、これより多くのコードです。私は、スレッドが生き続ける方法と、コールバックが自分自身を取り除く方法を欲しがっています。 – mac10688

+0

これは非同期NSOperationsのためのものです。カスタム 'NSOperation'を行い、' isAsynchronous'に対して 'true'を返し、' main() 'ではなく' start() 'をオーバーライドします。適切な時刻に(つまり、操作が完了したとき) 'isExecuting'と' isFinished'を手動で設定する必要があります。あなたは「スレッドが生き続ける」ことを望んでいません。あなたは、操作が正しい時刻に完了するようにしたい。これが非同期操作の仕組みです。つまり、main()が戻るときに、あなたが手で行うことを意味します。 –

答えて

1

悲しいことに、私は適切な修正のための時間がなかったので、タイムアウトの問題はできるだけ早く修正する必要がありました。私は仕事をしたものを見つけました。

//I have instantiated a class global NSOperation queue. 
[imageDownloadQueue addOperationWithBlock:^void() { 
    [task resume]; 
    while(task.state == NSURLSessionTaskStateRunning) 
    { 
     [NSThread sleepForTimeInterval:.1]; 
    } 
    }]; 

NSOperationはバックグラウンドスレッドで動作するため、タスクの実行中にそのスレッドをスリープ状態にできました。これによりスレッドが死ぬのを防ぎますが、タスクは自身のスレッド上で実行され、ブロックされません。

関連する問題