iOS GCD与异步块同步

时间:2015-04-12 17:59:06

标签: ios objective-c asynchronous block grand-central-dispatch

我有一个带有块的异步函数:

[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只等待块的结束。 如何让它等待其块中的异步函数结束?

2 个答案:

答案 0 :(得分:7)

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

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
});

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

答案 1 :(得分:1)

您可以将dispatch_asyncsemaphores

一起使用

示例:

- (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.example.MyApp", 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