Objective c 我可以使用GCD限制并发请求吗?

Objective c 我可以使用GCD限制并发请求吗?,objective-c,grand-central-dispatch,Objective C,Grand Central Dispatch,我正在从数据库异步获取数据。有没有办法将并发请求限制为一个数字,但仍然执行其余的请求 我看到了使用NSOperation和NSOperationQueue 但这对我来说太复杂了。 还有其他方法吗? GCD能做到吗 类似这样: ... //only make one of these obviously :) remaking it each time you dispatch_async wouldn't limit anything dispatch_semaphore_t concurren

我正在从数据库异步获取数据。有没有办法将并发请求限制为一个数字,但仍然执行其余的请求

我看到了使用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);
}

简单的方法是设置n个串行队列

struct dataCalls {
    let n:Int
    func fetchIt(){
        print ("Done",n)
    }

    init(n:Int){
        self.n=n
    }
}

var dataCallsArray: [dataCalls]=[]
var qArray:[dispatch_queue_t] = []
let n = 5
for i in 1...50 {
    dataCallsArray.append(dataCalls(n:i))
}

for _ in 1...n {
    qArray.append(dispatch_queue_create(nil, nil))
}

var i = 0
for data in dataCallsArray {
    dispatch_async(qArray[i%n], {() -> Void in data.fetchIt()})
    i++
}

我建议将此解决方案用于同步任务的有限并发执行:

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)
            }
        })
    }
}
这种方法的开销很小:除了当前执行的任务外,队列上只放了一个额外的任务(即一个额外的线程)。当你有大量的任务时,这尤其好


这是一个随时可用的演示,只需将代码放在操场上。

我想说使用
NSOperation
NSOperationQueue
比直接使用GCD更容易
NSOperationQueue
有一个非常方便的
maxConcurrentOperationsCount
属性。使用GCD,您需要实现自己的某种计数器。例如,您可以使用
dispatch\u信号量
函数系列…@Guillaume您有我可以看到的示例代码吗?我已经阅读了教程和类参考,但仍然不太理解。有关更多详细信息,请参阅Apple的,特别是本节。在
dispatch\u semaphore\u wait()
。这样,我们将在当前正在运行的任务之上只执行一个任务,而不是同时执行所有的N个任务。@werediver实际上,这不仅会更好,还会减少由于线程耗尽而导致死锁的可能性。在此解决方案中,当达到资源最大值时,任何进一步提交块的尝试都将创建一个新线程。这种情况一直持续到达到线程限制,然后应用程序可能会死锁。是的,2013年我显然没有考虑太多线程耗尽问题。如果有人想在feel free中编辑它,或者我会尽快开始。请注意,如果一些队列落后于其他队列,那么这将无法实现队列之间的负载平衡。