【发布时间】:2012-03-09 10:08:46
【问题描述】:
我需要将多个任务发送到 Grand Central Dispatch 以运行。有些任务会先完成,而有些任务会最后完成。
我如何知道我在 Grand Central Dispatch 中的所有任务都已完成?
我应该使用计数器来记录完成的任务数吗?有什么更聪明的方法吗?
【问题讨论】:
标签: ios
我需要将多个任务发送到 Grand Central Dispatch 以运行。有些任务会先完成,而有些任务会最后完成。
我如何知道我在 Grand Central Dispatch 中的所有任务都已完成?
我应该使用计数器来记录完成的任务数吗?有什么更聪明的方法吗?
【问题讨论】:
标签: ios
您可以使用调度组在所有任务完成时收到通知。这是来自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");
});
【讨论】:
如果你想控制一个任务在最后执行,可以使用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
【讨论】:
您可以在 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")
}
【讨论】: