例如,我有一个带有三个异步块的方法。需要每个块结果来执行下一个块以实现最终方法结果。所以,我正在寻找的是一个很好的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 }];
但在我的情况下,我遇到了一些问题,一些库方法使应用程序陷入僵局。 ><
答案 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);
您可能遇到的一个复杂问题是,尝试从完成处理程序中排队任务是否存在死锁风险,即,是否在处理入队任务的同一串行队列上调用完成处理程序。