我有一个错误(我已经第二次见面了)在我们的项目中,我只是在UIViewController视图的顶部添加一个视图。没什么了不起的,像这样:
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故障?
答案 0 :(得分:1)
一个有根据的猜测 - 并不是displayEmailNotificationsIfNeeded
无法在主线程上运行而不是明确地将其添加到队列中,这更多的是时间问题。由于故事板中的其他约束可能会在viewDidAppear
完成执行后处于不同状态时移动元素。在执行代码之前,异步添加执行块允许viewDidAppear
完成(以及在主队列上同步运行的任何其他内容)。
希望这有帮助。
答案 1 :(得分:0)
这不是一个肯定的答案,因为我需要重现这个错误,但这是我认为可能会发生的事情。
当你直接执行代码时,布局还没有完全准备好(这取决于你可能拥有的其他代码),因此布局错误。当您在dispatch_async
中显式运行代码时,您也在主线程上运行它,但是在稍后的某个时间点,直到布局准备好并且您看到正确的结果。
此外,执行此代码,您应该能够理解。
print("1");
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("2");
})
print("3");
答案 2 :(得分:0)
尝试在viewWillLayoutSubviews()
中运行它。此时,您的视图控制器.view
应该完全布局。请注意,此方法可能会被多次调用(例如:如果.view
调整大小)。