簡體   English   中英

DispatchQueue.sync與DispatchQueue.async之間的區別

[英]Difference Between DispatchQueue.sync vs DispatchQueue.async

我試圖了解調度同步和調度異步,我知道它以GCD的同步和異步方式執行。 但是當我嘗試下面的代碼時,它給了我奇怪的情況。

我在Playground和Sync塊中執行了3次測試以下代碼,而async塊給出了NSException。

//:基於UIKit的Playground,用於呈現用戶界面

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let que = DispatchQueue.init(label: "testing")
        // Executed 3 times
        que.sync {
            for i in 0...10 {
                print(i)
            }
        }
        // Giving me NSException
        que.async {
            let label = UILabel()
            label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
            label.text = "Hello World!"
            label.textColor = .black

            view.addSubview(label)
            self.view = view
            print("Label Added to Text View")
        }
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

為什么要執行3次同步塊。 以及為什么會有NSException錯誤。

同步將停止當前線程,直到完成您分配給它的任務。

異步將繼續當前線程,並在當前線程之后或之后執行任務。

為什么它有意外的行為?

這是因為loadView()希望在執行完view屬性后為其分配一個UIView,而您正在使用async進行操作,它將在loadView完成之后執行。

例外可能是因為您沒有按時分配UIView,或者是因為您正在私有隊列中處理UI。 UI應該始終在主線程中處理。

您的變量que是一個專用隊列,並且由於未指定否則它指向后台線程。

像這樣編輯代碼可能對您有幫助:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let que = DispatchQueue.init(label: "testing")
        // Executed 3 times
        que.sync {
            for i in 0...10 {
                print(i)
            }
        }
        // Giving me NSException
        DispatchQueue.main.async {
            let label = UILabel()
            label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
            label.text = "Hello World!"
            label.textColor = .black

            view.addSubview(label)

            print("Label Added to Text View")
        }
        self.view = view
    }
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM