我需要向Grand Central Dispatch发送多个任务才能运行。有些任务会先完成,有些则最后完成。
我怎么知道Grand Central Dispatch中的所有任务都已完成?
我应该使用计数器记录完成的任务数量吗?任何更聪明的方法?
答案 0 :(得分:23)
您可以使用调度组在所有任务完成时收到通知。这是http://cocoasamurai.blogspot.com/2009/09/guide-to-blocks-grand-central-dispatch.html
的示例dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,queue,^{
NSLog(@"Block 1");
});
dispatch_group_async(group,queue,^{
NSLog(@"Block 2");
});
dispatch_group_notify(group,queue,^{
NSLog(@"Final block is executed last after 1 and 2");
});
答案 1 :(得分:3)
如果要控制一个任务在最后执行,可以使用dispatch_group_t,如果您希望一个任务不仅在某些任务之后执行而且在某些任务之前执行,您可以使用dispatch_barrier_sync:
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{ printf("1");});
dispatch_async(queue, ^{ printf("2");});
dispatch_barrier_sync(queue, ^{ printf("3");});
dispatch_async(queue, ^{ printf("4");});
dispatch_async(queue, ^{ printf("5");});
可以打印
12345 or 21354 or ... but 3 always after 1 and 2, and 3 always before 4 and 5
如果您想要完全控制订单,可以使用dispatch_sync或Serial Dispatch Queue,或NSOperationQueue。如果您使用NSOperationQueue,请使用“addDependency”方法来控制任务的顺序:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op 1");
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op 2");
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op 3");
}];
//op3 is executed last after op2,op2 after op1
[op2 addDependency:op1];
[op3 addDependency:op2];
[queue addOperation:op1];
[queue addOperation:op2];
[[NSOperationQueue mainQueue] addOperation:op3];
它将始终打印:
op1 op2 op3
答案 2 :(得分:1)
您可以使用 swift 3 中的 DispatchGroup 使用GCD实现此目的。所有任务完成后,您都会收到通知。
let group = DispatchGroup()
group.enter()
run(after: 6) {
print(" 6 seconds")
group.leave()
}
group.enter()
run(after: 4) {
print(" 4 seconds")
group.leave()
}
group.enter()
run(after: 2) {
print(" 2 seconds")
group.leave()
}
group.enter()
run(after: 1) {
print(" 1 second")
group.leave()
}
group.notify(queue: DispatchQueue.global(qos: .background)) {
print("All async calls completed")
}