我应该如何等待 GCD 中的并行异步任务完成?

How should I wait for the completion of parallel async tasks in GCD?

dispatch_groupdispatch_group_notify() 是否是使用 GCD 在 Objective C 中等待并行异步任务完成的合理方法?

考虑以下几点:

dispatch_group_t requestGroup = dispatch_group_create();
dispatch_group_enter(requestGroup);
dispatch_group_enter(requestGroup);
[asyncCall1 completion:^{
    dispatch_group_leave(requestGroup);
}];

[asyncCall2 completion:^{
    dispatch_group_leave(requestGroup);
}];

dispatch_group_notify(requestGroup, dispatch_get_main_queue(), ^{
    // do something now that both async calls have completed
});

这是最简单、最好的方法吗?我问的原因是我有这样的代码并且通常它似乎可以工作,尽管我很少遇到像这样的崩溃:

libdispatch.dylib`dispatch_group_leave:
0x394ea4e8:  dmb    ishst
0x394ea4ec:  ldrex  r1, [r0, #0x28]
0x394ea4f0:  adds   r1, #0x1
0x394ea4f2:  strex  r2, r1, [r0, #0x28]
0x394ea4f6:  cmp    r2, #0x0
0x394ea4f8:  bne    0x394ea4ec                ; dispatch_group_leave + 4
0x394ea4fa:  cmp.w  r1, #0xffffffff
0x394ea4fe:  ble    0x394ea50e                ; dispatch_group_leave + 38
0x394ea500:  mvn    r2, #0x80000000
0x394ea504:  cmp    r1, r2
0x394ea506:  it     eq
0x394ea508:  beq.w  0x394edd54                ; _dispatch_group_wake
0x394ea50c:  bx     lr
0x394ea50e:  trap   
0x394ea510:  mov    r8, r8
0x394ea512:  mov    r8, r8

这是被调度组捕获的未连接崩溃吗?

如果要同步等待,可以利用dispatch_group_asyncdispatch_group_wait

更多详细信息(和示例):Waiting on groups of queued tasks

而且,虽然我没有使用过它,但我相信您也可以利用 dispatch_group_notifydispatch_group_async,这可能比进入和离开更干净一些?

@Rob 是正确的,并且存在一个完成块可以被调用两次的特定情况,这意味着对 dispatch_group_leave()dispatch_group_enter() 的调用是不平衡的,这是不受支持的。