データベースから非同期でデータを取得しています。同時リクエストを数に制限しながら、残りを実行する方法はありますか?
NSOperationとNSOperationQueueを使用した投稿を見ましたが、これは私には複雑すぎます。それを行う他の方法はありますか?GCDはそれを達成できますか?
データベースから非同期でデータを取得しています。同時リクエストを数に制限しながら、残りを実行する方法はありますか?
NSOperationとNSOperationQueueを使用した投稿を見ましたが、これは私には複雑すぎます。それを行う他の方法はありますか?GCDはそれを達成できますか?
このようなもの:
...
//only make one of these obviously :) remaking it each time you dispatch_async wouldn't limit anything
dispatch_semaphore_t concurrencyLimitingSemaphore = dispatch_semaphore_create(limit);
...
//do this part once per task, for example in a loop
dispatch_semaphore_wait(concurrencyLimitingSemaphore, DISPATCH_TIME_FOREVER);
dispatch_async(someConcurrentQueue, ^{
/* work goes here */
dispatch_semaphore_signal(concurrencyLimitingSemaphore);
}
同期タスクの同時実行を制限するには、次のソリューションをお勧めします。
func dispatch_async_batch(tasks: [() -> ()], limit: Int, completion: (() -> ())?) {
if tasks.count > 0 || completion != nil {
let q = dispatch_queue_create("dispatch_async_batch", DISPATCH_QUEUE_CONCURRENT);
let sema = dispatch_semaphore_create(limit);
dispatch_async(q, {
for task in tasks {
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
dispatch_async(q, {
task()
dispatch_semaphore_signal(sema)
})
}
if let completion = completion {
dispatch_barrier_async(q, completion)
}
})
}
}
このアプローチのオーバーヘッドはわずかです。現在実行中のタスクとは別に、追加のタスクが 1 つだけキューに置かれます (つまり、追加のスレッドが 1 つ)。全体的に大量のタスクがある場合に特に適しています。
この要点はすぐに使用できるデモです。コードをプレイグラウンドに配置するだけです。