【发布时间】:2017-04-21 05:38:12
【问题描述】:
dispatch_group 和 dispatch_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
这是被调度组捕获的未连接崩溃吗?
【问题讨论】:
-
如果您离开群组的次数多于进入的次数,您可以获得类似的东西。在您的情况下是否有任何可能发生这种情况?我可能会建议记录每次进入和每次退出,并确保它们匹配(或维护您自己的计数器)。显然,如果它像您的代码示例一样简单,那么这不太可能是问题,但如果它比这更复杂,这是需要敏感的一件事。
-
@Rob,我认为这是不可能的,因为这些是我为该组提供的唯一入口和出口。
-
好的,但是进入和离开组是我们许多人一直依赖的那些极其可靠的接口之一,所以我真的看不出问题中的简化代码示例如何可能生成你描述的崩溃。我怀疑问题出在其他地方(无关的请假电话,组标识符以某种方式重置等)。看起来崩溃在
dispatch_group_leave,所以如果你在堆栈跟踪中上升一帧,它应该带你到调用这个函数的代码,你可以在那里查看各种属性/变量。 -
对,我就是这么怀疑的。谢谢。
标签: objective-c grand-central-dispatch