等待异步块完成

时间:2014-11-28 06:09:38

标签: ios grand-central-dispatch

例如,我有一个带有三个异步块的方法。需要每个块结果来执行下一个块以实现最终方法结果。所以,我正在寻找的是一个很好的GCD策略,可以让他们按照严格的顺序执行并且没有死锁

__block id task1Result;    
__block id task2Result;    
__block id finalResult;  

[self startTask1:^(id result) { task1Result = result }]  

[self startTask2:task1Result block:^(id result) { task2Result = result }]  

[self startTask3:task2Result block:^(id result) { finalResult = result }]  

UPD。我找到了解决方案:

dispatch_semaphore_t sem = dispatch_semaphore_create(0);

__block id task1Result;    
__block id task2Result;    
__block id finalResult;  

[self startTask1:^(id result) { 
  task1Result = result;
  dispatch_semaphore_signal(sem);
}];  
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

[self startTask2:task1Result block:^(id result) { 
  task2Result = result;
  dispatch_semaphore_signal(sem);
}];  
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

[self startTask3:task2Result block:^(id result) { finalResult = result }];

但在我的情况下,我遇到了一些问题,一些库方法使应用程序陷入僵局。 ><

2 个答案:

答案 0 :(得分:3)

创建一个如下所述的串行调度队列:
https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

简而言之:

dispatch_queue_t queue;
queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_async(queue, ^{
    printf("Do some work here.\n");
});
dispatch_async(queue, ^{
    printf("When finished do next task.\n");
});

请注意,您必须自己处理队列。

答案 1 :(得分:-1)

如果每个任务直接消耗前一个任务的结果,你不能从其前任的完成回调中启动每个任务吗?但是,您仍然需要一个调度组来等待上一个任务完成。

dispatch_group_t group = dispatch_group_create();
__block id result;

dispatch_group_enter(group);
[self startTask1:^(id task1Result) {
  [self startTask2:task1Result block:^(id task2Result) {
    [self startTask3:task2Result block:^(id finalResult) {
      result = finalResult;
      dispatch_group_leave(group);
    }];
  }];
}];

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

您可能遇到的一个复杂问题是,尝试从完成处理程序中排队任务是否存在死锁风险,即,是否在处理入队任务的同一串行队列上调用完成处理程序。