iOS GCD与异步块同步

我有一个块的异步函数:

[self performAsyncTaskCompletion:(void(^) () ) { //Do Something } ]; 

我需要多次调用此函数,但需要以同步方式调用。 我试图使用GCD队列:

 dispatch_queue_t queue = dispatch_queue_create("com.MyApp.task", NULL); for (int i = 0; i < array.count; i++) { dispatch_sync(queue, ^{ [self performAsyncTaskCompletion:(void(^) () ) { //Do Something } ]; }); } 

但它不起作用,因为dispatch_sync只等待块的结束。 如何让它等待其块中的异步函数结束?

如果要在完成一系列异步任务后启动某个进程,可以使用调度组,但是希望允许这些任务相互之间并发运行(特别是对于网络请求,可以提供更好的性能)而不是顺序运行它们:

 dispatch_group_t group = dispatch_group_create(); for (int i = 0; i < array.count; i++) { dispatch_group_enter(group); [self performAsyncTaskCompletion: ^{ //Do Something dispatch_group_leave(group); }]; } dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // do this when its all done }); 

就个人而言,我甚至可能倾向于使用异步NSOperation子类模式执行performAsyncTaskCompletion的更激进的重构。 然后,您可以将这些添加到指定了NSOperationQueuemaxConcurrentOperationCount ,从而实现相同的并发性,同时还控制并发度。 但希望上面说明了这个想法:同时运行任务,但检测这些任务的完成,而不会阻塞主线程。

您可以将dispatch_async与信号量一起使用:

例:

 - (void)performAsyncTaskCompletion:(void (^)())block { if (block) { block(); } } - (void)runChainOfOperations { static dispatch_once_t onceToken; static dispatch_semaphore_t semaphore; static dispatch_queue_t queue; dispatch_once(&onceToken, ^{ semaphore = dispatch_semaphore_create(1); queue = dispatch_queue_create("com.MyApp.task", NULL); }); NSArray *array = @[@1, @2, @3, @4, @5]; static long counter = 0; for (int i = 0; i < array.count; i++) { dispatch_async(queue, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); [self performAsyncTaskCompletion:^{ sleep(10); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%ld", counter++); }); dispatch_semaphore_signal(semaphore); }]; }); } 

}

控制台输出:

 2015-04-12 21:28:06.047 HKTest[9497:1136830] 0 2015-04-12 21:28:16.023 HKTest[9497:1136830] 1 2015-04-12 21:28:26.025 HKTest[9497:1136830] 2 2015-04-12 21:28:36.029 HKTest[9497:1136830] 3 2015-04-12 21:28:46.031 HKTest[9497:1136830] 4