ios - dispatch_async(dispatch_get_main_queue(), ^{...});等到完成?

标签 ios objective-c multithreading grand-central-dispatch dispatch-async

我的应用程序中有一个场景,我想在一个方法中执行一些耗时的任务,其中包括一些数据处理以及 UI 更新。我的方法是这样的,

- (void)doCalculationsAndUpdateUIs {

    // DATA PROCESSING 1
    // UI UPDATE 1

    // DATA PROCESSING 2
    // UI UPDATE 2

    // DATA PROCESSING 3
    // UI UPDATE 3
} 

由于很耗时,我想在后台线程上进行数据处理,使用,

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{

但由于数据处理和 UI 更新是在同一个方法中,我只想在主线程中移动 UI 更新,

dispatch_async(dispatch_get_main_queue(), ^{

最后我的方法是这样的,

- (void)doCalculationsAndUpdateUIs {

    // DATA PROCESSING 1 
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI UPDATE 1
    });

    /* I expect the control to come here after UI UPDATE 1 */

    // DATA PROCESSING 2
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI UPDATE 2
    });

    /* I expect the control to come here after UI UPDATE 2 */

    // DATA PROCESSING 3
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI UPDATE 3
    });
}

这真的有效吗?这真的是一个好习惯吗?实现这一目标的最佳方法是什么?

附:这三个操作都是相互关联的。


编辑:对不起,伙计们。我在上面的代码中漏掉了一行。我的实际代码如下所示。

- (void)doCalculationsAndUpdateUIs {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // DATA PROCESSING 1 
        dispatch_async(dispatch_get_main_queue(), ^{
            // UI UPDATE 1
        });

        /* I expect the control to come here after UI UPDATE 1 */

        // DATA PROCESSING 2
        dispatch_async(dispatch_get_main_queue(), ^{
            // UI UPDATE 2
        });

        /* I expect the control to come here after UI UPDATE 2 */

        // DATA PROCESSING 3
        dispatch_async(dispatch_get_main_queue(), ^{
            // UI UPDATE 3
        });
    });
}

再次,我真的很抱歉造成困惑。

最佳答案

不,它不会等待,并且您在该示例中执行此操作的方式不是好的做法。

dispatch_async 始终是异步。只是您将所有 UI block 排入同一队列,因此不同的 block 将按顺序运行,但与您的数据处理代码并行运行。

如果您希望等待更新,您可以改用 dispatch_sync

// This will wait to finish
dispatch_sync(dispatch_get_main_queue(), ^{
    // Update the UI on the main thread.
});

另一种方法是将 block 嵌套入队。我不会推荐它用于多个级别。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Background work

    dispatch_async(dispatch_get_main_queue(), ^{
        // Update UI

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // Background work

            dispatch_async(dispatch_get_main_queue(), ^{
                // Update UI
            });
        });
    });
});

如果您需要更新 UI 以等待,那么您应该使用同步版本。让后台线程等待主线程是完全可以的。 UI 更新应该很快。

关于ios - dispatch_async(dispatch_get_main_queue(), ^{...});等到完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17490286/

相关文章:

ios - 如何在 ViewDidAppear 上使用 reloadData() 刷新 UITableView?

iphone - 必须在 CGContextBeginPath 之后调用 CGContextClosePath 吗?

c - 新手线程问题 (FFTW)

java - 虚拟线程是否在其被阻塞的同一承载线程中唤醒?

c++ - 当我使用 [=] 捕获(使用 Lambda 类)时,为什么变量会变为 'const'?

iphone - 我可以在我的 iOS 应用程序中使用第 3 方支付系统吗?

ios - UITableView如何在重新加载后继续滚动

ios - 如何获取 MPMediaItem(歌曲)收听时间(日期)

ios - Autolayout 与针对不同形状因子的不同 XIB?

objective-c - 两个childViewController之间的通信