Я понимаю, что все обновления пользовательского интерфейса должны выполняться из основного потока.
Но только ради более глубокого понимания того, как GCD и основная работа рассылки:
У меня есть кнопка, которая запускает сетевой вызов и в своем завершенииHandler я в конце концов делаю:
self.layer.borderColor = UIColor(red: 255/255.0, green: 59/255.0, blue: 48/255.0, alpha: 1.0).cgColor
self.layer.borderWidth = 3.0
Для изменения цвета требуется 6-7 секунд. Очевидно, что если запустить указанный код из основного потока, он сразу изменит цвет границы.
Question1, хотя у меня нет другого кода для запуска, почему переменные пользовательского интерфейса не происходят сразу из фонового потока? Что ждет?
Интересно, что если я нажму кнопку, чтобы сделать сетевой вызов, а затем коснитесь на самом текстовом поле (до 6-7 секунд), цвет границы изменится сразу.
Это происходит из-за:
Из фонового потока я обновил модель, то есть изменил цвет textField, который приостанавливает обновление пользовательского интерфейса/представления... но поскольку мы находимся в фоновом режиме, этот обновленный пользовательский интерфейс может занять несколько секунд
Но потом я сразу нажал на textField и заставил супер быстрый просмотр textField и всех его свойств, которые включают границу от основного потока (фактические касания пользователя всегда обрабатываются через основной поток)... которые хотя еще не красные на экране, но поскольку он краснеет на модели, он будет считывать из него и сразу меняет цвет на красный.
Question2: Правильно ли это наблюдение?
Если я не касаюсь и просто жду:
Если я нажимаю:
Мой полный код выглядит следующим образом:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func isValid(_ sender: Any) {
let userEmail = textField.text
let requestURL = NSURL(string: "https://jsonplaceholder.typicode.com")
var request = URLRequest(url: requestURL as! URL)
request.httpMethod = "POST"
let postString = "Anything"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
}
do {
let json = try? JSONSerialization.jsonObject(with: data, options: [])
if let _ = json as? [String: Any] {
self.textField.layer.borderColor = UIColor(red: 255/255.0, green: 59/255.0, blue: 48/255.0, alpha: 1.0).cgColor
self.textField.layer.borderWidth = 3.0
}
} catch let error as NSError {
print(error)
}
}
task.resume()
}
override func viewDidLoad() {
super.viewDidLoad()
}
}