在继续之前,如何等待经过dispatch_async? [英] How to wait past dispatch_async before proceeding?
问题描述
我正在执行一系列的dispatch_async,我只想在完成所有操作后才更新UI.问题是dispatch_async中的方法在单独的线程中调用某些东西,因此它在数据完全加载之前返回,而在加载所有内容之前调用dispatch_group_notify.
I have a series of dispatch_async that I am performing and I would like to only update the UI when they are all done. Problem is the method within dispatch_async calls something in a separate thread so it returns before the data is fully loaded and dispatch_group_notify is called before everything is loaded.
因此,我引入了一个无限循环,使其等待直到设置了标志为止. 这是最好的方法吗?参见下面的代码.
So I introduce a infinite loop to make it wait until a flag is set. Is this the best way? See code below.
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_group_wait()
(其中包括对超时的支持)呢?您可以使用dispatch_group_enter()
和dispatch_group_leave()
而不是dispatch_group_async()
来使组不完成,直到完成调用的第三方调用的内部块为止.
You're already aware of dispatch groups. Why not just use dispatch_group_wait()
, which includes support for a timeout? You can use dispatch_group_enter()
and dispatch_group_leave()
rather than dispatch_group_async()
to make the group not done until the internal block for the third-party call with completion is finished.
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_group_wait()
的使用确实使该代码同步,如果在主线程上运行,这是不好的.根据超时发生的确切情况,您可以像以前一样使用dispatch_group_notify()
并使用dispatch_after()
只是更新UI,而不是假装已完成的块.
The use of dispatch_group_wait()
does make this code synchronous, which is bad if run on the main thread. Depending on what exactly is supposed to happen if it times out, you could use dispatch_group_notify()
as you were and use dispatch_after()
to just updates the UI rather than trying to pretend the block completed.
更新:我调整了代码以确保更新UI"出现在主队列中,以防万一此代码不在主线程上.
Update: I tweaked my code to make sure that "update UI" happens on the main queue, just in case this code isn't already on the main thread.
顺便说一句,我只在调用thirdPartyCodeCallWithCompletion:
的块中使用了dispatch_async()
,因为您的原始文件使用了dispatch_group_async()
,而且我不确定该假设方法是否是异步的.不过,大多数带有完成块的API都是异步的.如果是这样的话,那么您可以直接调用它.
By the way, I only used dispatch_async()
for the block which calls thirdPartyCodeCallWithCompletion:
because your original used dispatch_group_async()
and I wasn't sure that the hypothetical method was asynchronous. Most APIs which take a completion block are asynchronous, though. If that one is, then you can just invoke it directly.
这篇关于在继续之前,如何等待经过dispatch_async?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!