Разница между DispatchQueue.sync и DispatchQueue.async - PullRequest
0 голосов
/ 12 февраля 2019

Я пытаюсь понять Асинхронную синхронизацию и диспетчеризацию, я знаю, что она выполняется синхронно и асинхронно в GCD.Но когда я попробовал приведенный ниже код, это дало мне странный сценарий.

Я тестировал приведенный ниже код в блоке Playground и Sync, выполненном 3 раза, а асинхронный блок дал исключение NSException.

//: UIKitигровая площадка на базе для представления пользовательского интерфейса

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.

1 Ответ

0 голосов
/ 12 февраля 2019

Синхронизация остановит текущий поток, пока он не завершит задачу, которую вы ему назначаете.

Async продолжит работу с текущим потоком и выполнитзадание параллельно или после текущего потока.

Почему он имеет непредвиденное поведение?

Это потому, что loadView() ожидает, что UIView будет назначено свойству view после его выполнения, что вы делаете с асинхронным выполнением, которое будет выполнено после завершения loadView.

Исключением может быть то, что вы не назначаете UIView вовремя или потому что вы обрабатываете пользовательский интерфейс в своей частной очереди.Пользовательский интерфейс всегда должен обрабатываться в главном потоке .

Ваша переменная 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()
...