ios - DispatchQueue.sync 与 DispatchQueue.async 之间的区别

标签 ios swift grand-central-dispatch

我试图了解 Dispatch Sync 和 Dispatch Async,我知道它以 GCD 的同步和异步方式执行。但是当我尝试下面的代码时,它给了我奇怪的场景。

我在 Playground 和同步块(synchronized block)中测试了以下代码执行了 3 次,异步 block 给出了 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次sync block。以及为什么会出现 NSException 错误。

最佳答案

Sync 将停止当前线程,直到它完成您分配给它的任务。

Async 将继续当前线程并并行或在当前线程之后执行任务。

为什么它有意想不到的行为?

那是因为 loadView() 期望在它被执行后将一个 UIView 分配给 view 属性,你正在使用异步执行它,这将是在 loadView 完成后执行。

异常可能是因为您没有按时分配 UIView 或因为您正在处理私有(private)队列中的 UI。 UI 应始终在主线程中处理。

你的变量 que 是一个私有(private)队列,因为你没有指定它指向一个后台线程。

像这样编辑您的代码可能会帮助您:

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()

关于ios - DispatchQueue.sync 与 DispatchQueue.async 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54649297/

相关文章:

Swift:判断NSProgressIndicator,异步刷新等待返回

objective-c - SharedApplication 值不可见

ios - 无法使用中央调度提高ios应用程序的运行速度

swift - 我如何在 Swift 3、Swift 4 及更高版本中使用 dispatch_sync、dispatch_async、dispatch_after 等?

ios - secondVC 中的结构数组未从 firstVC 附加

ios - 当解雇子父VC完全重新加载时

Xcode 6 测试版 : No such module 'Cocoa'

ios - AppCode 没有目标产品

ios - 无法创建 lldb private : Xcode can't run the app on iphone

ios - 指定 -sdk 选项时 xcodebuild 不起作用