ios - 在不分派(dispatch)到主队列的情况下更新 UI 元素

标签 ios objective-c uikit grand-central-dispatch

我有一个 dispatch_block_t 被传递给另一个函数,这个 block 将在函数时被调用> 完成异步任务。但问题是我不知道这个 block 将调用哪个线程

我想在主线程中更新我的用户界面,因此我想使用

dispatch_async(dispatch_get_main_queue(), ^{...})

更新我的用户界面。但如果发生这种情况,恐怕会导致死锁

dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
    dispatch_async(queue, ^{
        // outer block is waiting for this inner block to complete,
        // inner block won't start before outer block finishes
        // => deadlock
    });

    // this will never be reached
}); 

有没有办法防止死锁?就像在不使用 dispatch queue 的情况下更新 UI 元素一样。是否可以创建对 self弱引用 以更新 UI?

最佳答案

尝试使用 NSLogs 运行您的示例,您会发现死锁不会发生。这是因为使用 dispatch_async 只是将一个 block 提交到队列而不等待它完成执行(与 dispatch_sync 相反)。

所以运行这段代码:

dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{
    NSLog(@"1");
    dispatch_async(queue, ^{
        NSLog(@"2");
    });
    NSLog(@"3");
});

将产生以下日志:

Testtt[32153:2250572] 1
Testtt[32153:2250572] 3
Testtt[32153:2250572] 2

此外,我担心这里使用 dispatch_async(dispatch_get_main_queue(), ^{...}) 是确保消费者在主线程上获得结果的常用技术(即消费者不“关心”线程)。

为什么要使用 dispatch_block_t 来传递完成 block ?在我看来,在消费者端使用类似的东西有点令人困惑——我会传递一个匿名(没有 typedef) block 或为这些简单的完成 block 创建我自己的 typedef。

关于ios - 在不分派(dispatch)到主队列的情况下更新 UI 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51991011/

相关文章:

ios - 从我的 UITableView 中删除一个部分时出错

ios - 如何让我的导航栏在 iOS 7 上完全透明?

ios - 为什么我不能创建 NSLayoutConstraint 类型的数组?

ios - 如何使用 UIWebView 消除内存泄漏?

ios - AVAudioSession outputVolume 未在 iOS 9+ 上更新

iphone - 自定义委托(delegate)仅在从 UIButton 选择器 ARC 保留问题直接调用时才有效

iphone - 释放 UIViewController

iphone - 如何将当前方法的名称或签名放入 NSString?

ios - 在 shouldPerformSegue 中显示 UIAlertViewController

android - 跨平台开发基于服务器的游戏,包括iphone、android、WP7