UI故障,尽管在主线程上运行UI操作的事实
我在我的项目中有一个错误(我已经第二次遇到),我只需在UIViewController视图的顶部添加一个视图。什么都不突出,像这样:UI故障,尽管在主线程上运行UI操作的事实
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.displayEmailNotificationsIfNeeded()
}
的错误是,由于某种原因,自动布局不正确地工作,并在顶部不加它,而是围绕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
两种情况。这不是很糟糕,但出于好奇,我想了解是什么原因造成的。有没有办法调试这种情况,并理解为什么在主线程上明确执行操作修复了一些UI故障?
一个受过教育的猜测 - 并不是说displayEmailNotificationsIfNeeded
没有在主线程上运行,也没有明确地将其添加到队列中,这更多的是时间问题。由于故事板中的其他约束一旦执行viewDidAppear
就会处于不同状态,因此可能会有元素四处移动。异步添加执行块允许viewDidAppear
在执行代码之前完成(以及其他任何在主队列上同步运行)。
希望这会有所帮助。
这不是一个确定的答案,因为我需要重现错误以确定,但这里是我认为可能发生的事情。
当您直接执行代码时,布局未完全准备好(取决于您可能具有的其他代码),因此布局错误。当您明确运行dispatch_async
中的代码时,您也正在主线程上运行它,但是在稍后的时间点,直到布局准备就绪,您会看到正确的结果。
此外,执行此代码,你应该能够理解。
print("1");
dispatch_async(dispatch_get_main_queue(), {() -> Void in
print("2");
})
print("3");
尝试在viewWillLayoutSubviews()
中运行它。此时,您的视图控制器.view
应该完全布局。请注意,此方法可能会多次调用(例如:如果.view
被调整大小)。