Неожиданное поведение макета без DispatchQueue.main.async - PullRequest
0 голосов
/ 28 мая 2018

Иногда, когда автоматическое расположение или изменения пользовательского интерфейса не выполняются так, как я хочу, я оборачиваю код в DispatchQueue.main.async, и это решается (например):

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    DispatchQueue.main.async {
        self.tableview.reloadData()
    }
}

Но отлаживаем этот код с помощью (Thread.current) без DispatchQueue он говорит мне, что он уже находится в главном потоке, но не выполняет анимацию, и просто добавление DispatchQueue.main.async работает нормально.Я хотел бы знать, что делает DispatchQueue.main.async, чтобы это работало.Потому что я думал, что это просто сделано, чтобы код выполнялся в основном потоке, но если он уже выполняется в основном потоке, он ничего не должен делать ... Но с этим он работает нормально и без проблем с компоновкой.

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

Я думал, что это может быть потому, чтозадержка, генерируемая dispatchQueue, но это случалось со мной в других местах, где задержка не нужна ( Swift Animate длительность не работает в CGAffineTransform -> Сегодня я отладил эту проблему без dispatchMainQueue, и этовыполняется также в основном потоке, но он не работает без отправки)

1 Ответ

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

Проще говоря, когда вы используете DispatchQueue.main.async, self.tableview.reloadData() будет вызываться после небольшой задержки (потому что блок будет выполнен в следующем цикле).Вот почему у вас есть разница.

В этом случае viewWillTransition(to:with:) выполняется, когда устройство будет повернуто.Это означает, что что-то может быть не так в данный момент, и устройство еще не вращалось.Поэтому, если вы позвоните self.tableview.reloadData(), это может дать неправильный результат.

Почему DispatchQueue.main.async решает проблему? - Это потому, что DispatchQueue.main.async дает задержку перед выполнением блока ис этой задержкой, self.tableview.reloadData() будет вызван после того, как устройство завершит вращение.Вот почему он дает правильный результат

Сделайте это с animate(alongsideTransition:completion:), и вам не нужно будет использовать DispatchQueue.main.async

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
  coordinator.animate(alongsideTransition: nil, completion: { (_) in
    self.tableview.beginUpdates()
    self.tableview.endUpdates()
  })
}
...