Как показать строку одну за другой в асинхронном коде? - PullRequest
0 голосов
/ 17 мая 2018

Я хочу сделать цикл for с помощью async. Для имитации асинхронности я добавил несколько задержек.

import Cocoa

class ViewController: NSViewController {
    private let semaphore = DispatchSemaphore(value: 0)
    private let concurrentQueue = DispatchQueue.global()

    override func viewDidLoad() {
        super.viewDidLoad()

        for i in 1...10 {
            if run(i) {
                break
            }
        }
    }

    func run(_ i:Int) -> Bool{
        let seed = arc4random()
        let isSuccess = seed % 5 == 1
        let delayInSeconds = Int(seed % 3)

        concurrentQueue.asyncAfter(wallDeadline: .now() + .seconds(delayInSeconds)) {
            DispatchQueue.main.async {
                self.textView.string += "\(i)\t\(seed)\n"
            }

            self.semaphore.signal()
        }

        semaphore.wait()

        return isSuccess
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBOutlet var textView: NSTextView!
}

Проблема в том, что при запуске кода все строки добавляются одновременно. Я хочу, чтобы он добавлялся один за другим. Есть идеи?

1 Ответ

0 голосов
/ 17 мая 2018

Проблема решена.Причина, по которой обновление пользовательского интерфейса не работает, заключается в том, что func run() работает в основном потоке, который всегда блокируется semaphore.wait().Чтобы решить проблему, просто добавьте ее в другой поток.

override func viewDidLoad() {
    super.viewDidLoad()

    concurrentQueue.async {
        for i in 1...10 {
            if self.run(i) {
                break
            }
        }
    }
}
...