2016-04-25 41 views
0

我在我的項目中有一個錯誤(我已經第二次遇到),我只需在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故障?

回答

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被調整大小)。

相關問題