7

データベースから非同期でデータを取得しています。同時リクエストを数に制限しながら、残りを実行する方法はありますか?

NSOperationとNSOperationQueueを使用した投稿を見ましたが、これは私には複雑すぎます。それを行う他の方法はありますか?GCDはそれを達成できますか?

4

3 に答える 3

17

このようなもの:

...
//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);
}
于 2013-01-28T04:46:31.430 に答える
0

同期タスクの同時実行を制限するには、次のソリューションをお勧めします。

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 つ)。全体的に大量のタスクがある場合に特に適しています。

この要点はすぐに使用できるデモです。コードをプレイグラウンドに配置するだけです。

于 2016-04-28T13:36:14.583 に答える