Swift основной цикл для обновления вида - PullRequest
0 голосов
/ 23 октября 2019

Я новичок в Swift и пытаюсь реализовать простое тестовое приложение Single-View: после запуска оно должно автоматически добавлять текстовые строки в UITextView.

Однако все, что я получаю, это пустой экран со следующим кодом:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var m_logView: UITextView!

    private let m_log = Log()
    override func viewDidLoad() {
        super.viewDidLoad()
        addLog(msg: "Hello World!")

        while true {
            m_log.requestLog{ [weak self] (data: String) in
                self?.consumeLog(log: data)
            }
        }
    }

    func consumeLog(log: String) {
        addLog(msg: log)
    }

    func addLog(msg: String) {
        m_logView.text += msg + "\n"
    }
}

class Log {
    func requestLog(consume: (_ log: String) -> Void) {
        let log = "Data from wherever"
        consume(log)
    }
}

Я подозревал, что пытаюсь обновить UITextView не в том месте. Приведенный выше код просто блокирует viewDidLoad() от завершения и отображения UITextView.

Итак, я нашел viewDidAppear, но на этот раз он застрял там и показывает только "Hello World!"в представлении.

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var m_logView: UITextView!

    private let m_log = Log()
    override func viewDidLoad() {
        super.viewDidLoad()
        addLog(msg: "Hello World!")
    }

    override func viewDidAppear(_ animated: Bool) {
        while true {
            m_log.requestLog{ [weak self] (data: String) in
                self?.consumeLog(log: data)
            }
        }
    }

    func consumeLog(log: String) {
        addLog(msg: log)
    }

    func addLog(msg: String) {
        m_logView.text += msg + "\n"
    }
}

class Log {
    func requestLog(consume: (_ log: String) -> Void) {
        let log = "Data from wherever"
        consume(log)
    }
}

Большинство обучающих программ по MVC для iOS, которые я обнаружил, учат тому, как реализовывать взаимодействия с пользователем, но избегайте того, как обновлять представление путем программного изменения модели из бэкэнда.

Я, вероятно, ищу обратного вызова / делегата, где я могу обновить UITextView, связанный с его моделью данных, когда данные изменяются, но где это?

1 Ответ

1 голос
/ 23 октября 2019

Цикл while совершенно неуместен, так как вызывает тупик.

Используйте Timer, который работает асинхронно

Замените

while true {
    m_log.requestLog{ [weak self] (data: String) in
        self?.consumeLog(log: data)
    }
}

на

Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { [weak self] _ in 
    m_log.requestLog{ data in
        self?.consumeLog(log: data)
    }
}

И вы можете явно обновить пользовательский интерфейс в основном потоке

func addLog(msg: String) {
    DispatchQueue.main.async {
        m_logView.text += msg + "\n"
    }
}

Примечание:

В соответствии с именными переменными Swift lowerCamelCased например mLogView

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...