为什么设置为后台的服务质量在主线程中运行?

时间:2017-03-31 11:11:47

标签: ios swift multithreading grand-central-dispatch

为什么下面的代码在主线程中运行,虽然我已经为背景线程指定了qos?

func testQueue(){

    let queue = DispatchQueue(label: "com.appcoda.myqueue",qos:.background)
    queue.sync {

        if Thread.isMainThread{
            print("is in main thread")
        }else{
            print("is i background thread")
        }
        for i in 100..<110 {
            print("Ⓜ️", i)
        }
    }
}

testQueue()

每当我尝试运行该方法时,我会在控制台中以is in main thread获取msg,这不应该是这种情况。我正在读这篇文章。

http://www.appcoda.com/grand-central-dispatch/

请参阅“调度队列入门”部分。

2 个答案:

答案 0 :(得分:5)

您指定了后台队列,而不是后台线程。在队列上调度任务时,GCD会查找要运行任务的线程。

由于您使用的是同步调度,主队列被阻止,主线程可以自由执行,因此您的任务在主线程上执行。

  • 队列 上发送的任务将在主线程上运行
  • 在另一个队列上发送的任务 可能在主线程或其他线程上运行

答案 1 :(得分:1)

以下是解决方案: -

主线程的默认值始终为同步,因此无论您使用哪些属性创建了哪个队列,当它被声明为同步时,它将始终在主线程中运行

Refer this Image

第二件事主线程也可以在异步中运行,它将保证这个新任务将在当前方法完成后的某个时间执行。

第三件事是当您使用 async 尝试相同的代码时,它将正常工作。

Refer this image

请参阅以下代码并弄清楚: -

func testQueue(){

    let queue = DispatchQueue(label: "com.appcoda.myqueue",qos:.background, attributes:DispatchQueue.Attributes.concurrent)

    queue.sync {   //Sync will always create main thread

        if Thread.isMainThread{
            print("is in main thread")
        }else{
            print("is i background thread")
        }
    }

    DispatchQueue.main.async { //Main thread can be async
        if Thread.isMainThread{
            print("is in main thread")
        }else{
            print("is i background thread")
        }

    }

    if Thread.isMainThread { //default is Main thread sync
        for i in 100..<110 {
            print("Ⓜ️", i)
        }
    }
    else{
        print("is i background thread")
    }

    queue.async {   //Here your custom async thread will work
        if Thread.isMainThread{
            print("is in main thread")
        }else{
            print("is i background thread")
        }
    }

}

testQueue()