2016-04-25 1 views
0

У меня есть ошибка (которую я встречаю уже второй раз) в нашем проекте, где я просто добавляю представление в верхней части представления UIViewController. Ничего выдающегося, что-то вроде этого:Недостатки пользовательского интерфейса, несмотря на то, что операции пользовательского интерфейса выполняются по основной теме

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    self.displayEmailNotificationsIfNeeded() 
} 

Исправлена ​​ошибка не в том, что по какой-то причине Auto Layout работает неправильно и не добавить его в верхней части, а вокруг 60pt ниже, чем это необходимо. Я подозреваю, что ~ 60pt исходит из ручной регулировки ограничения сверху, чтобы включить панель навигации и строку состояния, но это не очень важно.

Дело в том, что проблема исчезает, если я запускаю метод явно на главной очереди, как это:

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    print("is main thread: ", NSThread.isMainThread()) 
    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     print("is main thread inside block: ", NSThread.isMainThread()) 
     self.displayEmailNotificationsIfNeeded() 
    }) 
} 

печати заявления вернуться true для обоих случаев. Это не ужасно, но просто из любопытства я хочу понять, что это за причина. Есть ли способ отладить эту ситуацию и понять, почему явное выполнение операций с основным потоком устраняет некоторые сбои пользовательского интерфейса?

ответ

1

Понятно, что displayEmailNotificationsIfNeeded не работает в основном потоке, если вы не добавили его в очередь явно, это скорее вопрос времени. Могут быть элементы, перемещающиеся в результате других ограничений в вашем раскадровке, которые находятся в другом состоянии, когда viewDidAppear заканчивает выполнение. Добавляя блок выполнения асинхронно, завершите (viewDidAppear) (и все, что выполняется синхронно в главной очереди) перед выполнением кода.

Надеюсь, это поможет.

0

Это не определенный ответ, поскольку мне нужно воспроизвести ошибку, чтобы быть уверенным, но вот что, по-моему, могло бы произойти.

Когда вы выполняете код напрямую, макет не полностью готов (это зависит от другого кода, который у вас может быть) и, следовательно, неправильного расположения. Когда вы явно запускаете код в dispatch_async, вы запускаете его также в основном потоке, но в более поздний момент времени и до тех пор, пока макет не будет готов, и вы увидите правильный результат.

Также выполните этот код, и вы должны быть в состоянии понять.

print("1"); 
    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     print("2"); 
    }) 
    print("3"); 
0

Попробуйте запустить его в viewWillLayoutSubviews(). Контроллеры вашего вида .view должны быть полностью выложены на этом этапе. Обратите внимание, что этот метод можно назвать несколько раз (например: если .view получает изменение размера).

Смежные вопросы