首页 > 解决方案 > 从主线程上的队列调度到主线程

问题描述

我有一个非常奇怪的情况,我有多个嵌套的调度队列,并且在某些时候我需要更新 UI。DispatchQueue.main.async如果我已经在主线程上,则不会执行,如果我跳过它,我可以在调试器(以及 using Thread.isMainThread)中看到我在主线程上但在自定义队列之一中并且 UI 不会更新. 我如何进入“真正的”主线程(com.apple.main-thread)?或者我如何确保通过

private let progressQueue = DispatchQueue(label: "custom_thread", attributes: .concurrent)

绝对是后台线程?

标签: iosmultithreadinggrand-central-dispatch

解决方案


您的断言“如果我已经在主线程上,则 DispatchQueue.main.async 不会执行”是不正确的。当您调度一个代码块时,该块被放置在队列中并按顺序执行,例如考虑以下代码:

    print ("hello #1 \(Thread.current.description) isMain=\(Thread.isMainThread)")

    DispatchQueue.global().async {
        print ("hello #2 \(Thread.current.description) isMain=\(Thread.isMainThread)")
        
        DispatchQueue.main.async {
            print ("hello #3 \(Thread.current.description) isMain=\(Thread.isMainThread)")
        }
    }

    DispatchQueue.main.async {
        print ("hello #4 \(Thread.current.description) isMain=\(Thread.isMainThread)")
    }
    
    let progressQueue = DispatchQueue(label:"custom_thread", attributes: .concurrent)
    progressQueue.async {
        print ("hello #5 \(Thread.current.description) isMain=\(Thread.isMainThread)")

    }

结果控制台输出:

hello #1 <NSThread: 0x2824c8380>{number = 1, name = main} isMain=true
hello #2 <NSThread: 0x2824f6740>{number = 3, name = (null)} isMain=false
hello #5 <NSThread: 0x2824f6740>{number = 3, name = (null)} isMain=false
hello #4 <NSThread: 0x2824c8380>{number = 1, name = main} isMain=true
hello #3 <NSThread: 0x2824c8380>{number = 1, name = main} isMain=true

请记住,后台队列可以随时执行。唯一可以确定的是 hello #1 将首先出现,并且 hello #2 将出现在 hello #3 之前。

你还可以看到,progressQueue它绝对是一个后台线程,并且看起来和全局调度队列一样。


推荐阅读