1. 程式人生 > >等待多個異步操作

等待多個異步操作

enc 指定 結束 ati something sop patch 多少 barrier

例如這樣一個場景,有三個異步操作A,B,C, AB相互不依賴,但是操作C需要等AB都執行結束後才能執行

方法一 dispatch_group

dispatch_group_t group = dispatch_group_create();

dispatch_queue_t queue = dispatch_queue_create("a", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(group, queue, ^{

NSLog(@"block A start");

sleep(5);

NSLog(@"block A end");

});

dispatch_group_async(group, queue2, ^{

NSLog(@"block B start");

sleep(10);

NSLog(@"block B end");

});

dispatch_group_notify(group, queue3, ^{

NSLog(@"block C start");

});

原理:dispatch_group可以監測多個block對象,記錄當前group中有多少個block對象在執行,並在當前group中的所有block對象都執行完之後執行一個特定的block。具體方法為 dispatch_group_async方法可以將block加入到指定的dispatch_group中(可以理解為數量上+1),當block執行結束時再將其移除,而dispatch_group_notify方法會在指定的group中所有的block都執行完之後再去執行相應的block

方法二: dispatch_barrier_async

dispatch_async(queue, ^{

NSLog(@"block A start");

sleep(5);

NSLog(@"block A end");

});

dispatch_async(queue, ^{

NSLog(@"block B start");

sleep(10);

NSLog(@"block B end");

});

dispatch_barrier_async(queue, ^{

NSLog(@"block C start");

});

原理:通過dispatch_barrier_async添加的block會在當前異步隊列中在它之前添加的其他的block都執行完畢後才執行自己的block,在dispatch_barrier_async之後添加的block會等通過dispatch_barrier_async添加的block執行完畢之後才會執行

方法三:NSOperationQueue

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];

NSOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"block A start");

sleep(5);

NSLog(@"block A end");

}];

NSOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"block B start");

sleep(10);

NSLog(@"block B end");

}];

NSOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"block C start");

}];

[operation3 addDependency:operation1];

[operation3 addDependency:operation2];

[operationQueue addOperation:operation1];

[operationQueue addOperation:operation2];

[operationQueue addOperation:operation3];

原理:NSOperationQueue支持添加dependency

方法四:dispatch_group_enter dispatch_group_leave

以上三種方法適用場景為我們能夠控制異步返回block的情況,當我們對異步返回的block沒有控制權時,比如有回調block的方法,上述方法就失效了,此時就需要用到 dispatch_group_enter dispatch_group_leave

比如有一個方法

- (void)handleSomethingForSeconds:(NSInteger)seconds withCompletion:(void (^)())completion

我們對completion沒有直接控制權此時需要如下處理

dispatch_group_t group2 = dispatch_group_create();

dispatch_group_enter(group2);

[self handleSomethingForSeconds:5 withCompletion:^{

NSLog(@"complete A");

dispatch_group_leave(group2);

}];

dispatch_group_enter(group2);

[self handleSomethingForSeconds:10 withCompletion:^{

NSLog(@"complete B");

dispatch_group_leave(group2);

}];

dispatch_group_notify(group2, queue, ^{

NSLog(@"block C start");

});

原理:dispatch_group_enter會顯示地給指定group中記錄的正在執行的block數加一,dispatch_group_leave會顯示地給指定group中記錄的正在執行的block數減一,其他原理跟方法一相同,以此來實現等待的目的。

等待多個異步操作