Objective c 如何在继续之前等待超过分派\u async?
我正在执行一系列的dispatch_async,我只想在它们全部完成后更新UI。问题是dispatch_async中的方法在单独的线程中调用某些内容,因此它在数据完全加载之前返回,并且在加载所有内容之前调用dispatch_group_notify 所以我引入了一个无限循环,让它等待一个标志被设置。 这是最好的方式吗?请参阅下面的代码Objective c 如何在继续之前等待超过分派\u async?,objective-c,grand-central-dispatch,Objective C,Grand Central Dispatch,我正在执行一系列的dispatch_async,我只想在它们全部完成后更新UI。问题是dispatch_async中的方法在单独的线程中调用某些内容,因此它在数据完全加载之前返回,并且在加载所有内容之前调用dispatch_group_notify 所以我引入了一个无限循环,让它等待一个标志被设置。 这是最好的方式吗?请参阅下面的代码 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();
for (...) {
dispatch_group_async(group, queue, ^{
__block BOOL dataLoaded = NO;
[thirdPartyCodeCallWithCompletion:^{
dataLoaded = YES;
}];
// prevent infinite loop
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)),
queue, ^{
dataLoaded = YES;
});
// infinite loop to wait until data is loaded
while (1) {
if (dataLoaded) break;
}
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//update UI
});
}
您已经知道调度组。为什么不使用包含超时支持的
dispatch\u group\u wait()
?您可以使用dispatch\u group\u enter()
和dispatch\u group\u leave()
而不是dispatch\u group\u async()
使组在完成第三方调用的内部块之前不完成
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();
for (...) {
dispatch_group_enter(group);
dispatch_async(queue, ^{
[thirdPartyCodeCallWithCompletion:^{
dispatch_group_leave(group);
}];
}
}
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, NSECS_PER_SEC));
dispatch_async(dispatch_get_main_queue(), ^{
//update UI
});
使用
dispatch\u group\u wait()
确实会使此代码同步,如果在主线程上运行,这是不好的。根据超时时实际发生的情况,您可以原样使用dispatch\u group\u notify()
,并使用dispatch\u after()
只更新UI,而不是假装块已完成
更新:我调整了代码,以确保“更新UI”发生在主队列上,以防主线程上还没有该代码 顺便说一下,我只对调用第三方代码调用WithCompletion:的块使用了
dispatch\u async()
,因为您最初使用的是dispatch\u group\u async()
,我不确定假设的方法是异步的。不过,大多数采用完成块的API都是异步的。如果是,那么您可以直接调用它。另一种方法是使用和:
无限循环从来都不是最好的方式:)试试分派信号灯;看到真棒@jatoben,谢谢!嗨,肯,我使用你建议的方法,但代码被卡住了-从未调用过更新UI。我的信号量方法没有这个问题。我把超时参数弄错了
dispatch\u group\u wait()
。我经过一个三角洲,但它需要一个绝对时间。我已经修好了密码。
// Create your semaphore, 0 is specifying the initial pool size
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@autoreleasepool {
// Your code goes here
}
// Release the resource and signal the semaphore
dispatch_semaphore_signal(semaphore);
});
// Wait for the above block execution, AKA Waits for (decrements) a semaphore.
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// After this line you can now safely assert anything you want regarding the async operation since it is done.