为什么我们从线程中移出闭包在 Grand Central Dispatch 中被调用?

Why are We Moved from the Threads Closures are called On in Grand Central Dispatch?

我正在 Swift 了解 Grand Central Dispatch。我了解到您可以创建自己的队列来执行代码。我还了解到,您可以通过调用 mainreturn 到主线程。我一直在使用断点来观察线程,因为代码正在执行,试图更好地理解 GCD。我注意到以下内容并试图理解它。

  1. 我创建了自己的队列,名为 downloadQueue。我在这个队列上从 URLSession 调用 dataTask,并且在调用 dataTask() 的行上看到我在我创建的 downloadQueue 中。

  1. 在我进入 dataTask() 的完成处理程序的那一刻,我就不再在 downloadQueue 上了。我移动到队列:NSOperationQueue.

下面的代码是我的dataTask()。

let downloadQueue = DispatchQueue(label: "downloadQueue", attributes: [])

downloadQueue.async { () ->

中无效
    let dataTask = self.session!.dataTask(with: self.sessionURL!, completionHandler: { (data, response, error) -> Void in
    
    if error == nil
    {
        if data != nil
        {
            // Handle Data
        }
        else
        {
            // Handle Error
        }
    }
    else if error != nil
    {
        self.sendErrorCodeEmail(errorCodeMessage)  // The line from image2
    }
})

dataTask.resume()

}

我的理解是 downloadQueue.async{} 闭包中的所有代码都是在 downloadQueue 上执行的。为什么我会转到另一个队列?

  1. 如果我回调主线程,同样的事情也适用。一旦我进入 DispatchQueue.main.async{} 闭包,我就会回到 Queue: NSOperationQueue。这是为什么?

"Why"问题总是有点搞笑。从最直接的意义上来说,because that's just how URLSession works:

All delegate method calls and completion handlers related to the session are performed on this queue.