调度组和 NSNotification

Dispatch group and NSNotification

我的问题很简单。我有 3 个任务,一个是由 NSNotification 触发的。 如何等待所有任务完成后再继续。

到目前为止,我尝试使用调度组但找不到添加由 NSNotification 触发的任务的方法。 (我尝试在 NSNotification 触发的方法中添加 dispatch 命令,但如果通知在任务 1 和 2 之后出现,则添加到组中为时已晚,因为它已经完成。)

_asyncDispatch = dispatch_group_create();


dispatch_group_async(_asyncDispatch,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
    [self doTask1];
});

dispatch_group_async(_asyncDispatch,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
    [self doTask2];
});

dispatch_group_notify(_asyncDispatch,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {

    // We're done!
});

我建议您改用 NSOperationNSOperationQueue。您可以 link 所有操作作为 dependency 彼此进行,并等待所有三个操作完成。然后在最后一个操作的完成块中执行完成处理程序。

如果您对此感到困惑,您仍然可以使用调度组,但方式稍有不同。使用 dispatch_group_enter/dispatch_group_leave + dispatch_group_wait。类似的东西:

dispatch_group_t waitGroup = dispatch_group_create();
dispatch_group_enter(waitGroup);
dispatch_async(otherQueue, ^{
    //long-running code
    dispatch_group_leave(waitGroup);
}
dispatch_group_wait(waitGroup, DISPATCH_TIME_FOREVER);

在您的一项任务开始时 运行 调用 dispatch_group_enter,在任务完成后 dispatch_group_leave 调用。在需要等待所有任务完成的地方调用dispatch_group_wait不要在主线程中等待!最好为此创建一个单独的队列。

但我鼓励您使用 NSOperations。它更加可控并且能够取消。

感谢@Sega-Zero 的指导。这是我实施的解决方案。

_operationQueue = [[NSOperationQueue alloc] init];
_semaphore = dispatch_semaphore_create(0);

NSOperation *uploadOperation = [NSBlockOperation blockOperationWithBlock:^{
    [self doFirstTask];
}];

NSOperation *downloadOperation = [NSBlockOperation blockOperationWithBlock:^{
    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
}];
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
    [self doNextMethod];
}];

[completionOperation addDependency:uploadOperation];
[completionOperation addDependency:downloadOperation];

[_operationQueue addOperations:@[uploadOperation, downloadOperation, completionOperation] waitUntilFinished:NO];

然后,在NSNotification

触发的方法中
-(void)methodTriggeredByNotif:(NSNotification *)notification {

// doing some serious stuff here and when done
dispatch_semaphore_signal(_semaphore);}

瞧。感谢大家。