我的应用程序中有一个场景,我想用一种方法完成一些耗时的任务,包括一些数据处理和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更新都采用相同的方法,我只想使用,

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
    });
}

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

另外,这三项业务都是相互关联的.


EDIT:个抱歉的家伙.我有missed a line in the above code个.我的实际代码是这样的.

- (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永远是asynchronous.只是将所有UI块排队到同一个队列中,这样不同的块将按顺序运行,但与数据处理代码并行.

如果您想让更新等待,可以使用dispatch_sync.

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

另一种方法是嵌套块排队.不过,我还是建议多层次使用它.

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更新应该非常快.

Objective-c相关问答推荐

NSMutableDictionary 的深层可变副本

iPhone 可达性判断

如何向 UILabel 添加滚动功能

检测 NSString 的语言

对 nil 对象进行快速枚举

iOS:使用设备修饰符加载 xib 文件?

iOS:如何将 UIViewAnimationCurve 转换为 UIViewAnimationOptions?

为什么 NSOrderedSet 不继承自 NSSet?

动画 UIButton 状态变化

关闭一次后如何返回允许推送通知对话框?

Objective-C 的 NSMutableArray 是线程安全的吗?

如何在 UIAlertController 中添加 textField?

Cocoapods ld:找不到-lPods-Projectname 的库

iOS 11 large-title导航栏不折叠

导航返回时重新加载 UITableView?

writeToFile:atomically: atomically 是什么意思?

iOS 7 中的 UITextView 链接检测

为什么 Select Emacs/Vim/Textmate? Xcode 还不够好吗?

如何调整 UITableView 中原型单元格的左边距?

Objective C 消息分发机制