2016-06-10 27 views
2

我正在更新關鍵部分內的窗口。因爲在這個窗口中被繪製的數據被其他人(在另一個關鍵部分內)訪問,所以我想要確保被繪製的窗口在我退出臨界區時更新。如何確保NSWindow在代碼塊的末尾重新繪製

在Windows中,我可以使用InvalidateRect後跟UpdateWindow以確保存在強制繪製,並且執行消息而不是簡單地將其推入隊列,稍後標記爲執行。

什麼是在OSX中實現相同效果的相應方法?

從文檔,似乎是這樣的:

[myWindow display]其中myWindowNSWindow類型應該做的伎倆,但它不會立即繪製它。

有什麼建議嗎?

+0

所以你運行一個線程中的關鍵部分? –

回答

2

您可以通過在窗口中包含的視圖上調用[self setNeedsDisplay]來強制執行它,然後在短時間內運行一個小運行循環以允許繪製消息傳播到顯示邏輯。

[viewToRefresh setNeedsDisplay]; 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 

這可能工作。它是一個相當奇怪的場景!因人而異。

+0

我已經嘗試過,但我對運行循環的混亂有點懷疑。任何可能證實這樣做的參考是安全的? – TheBlueNotebook

+0

我們一直在代碼中使用這個非常不同的場景來允許通知通過。這不是一個想法的情況(通常我寧願重構代碼以去除依賴),但基本上Cocoa繪製循環不受您的控制。 –

1

首先,你從來沒有畫過一個窗口。你可以繪製視圖。窗戶只是視圖的容器。

其次,視圖應該知道自己,何時何地需要重新繪製。如果下方的數據發生變化,則報告該情況,但不報告請求。這是因爲控制器不能禁止,視圖的哪個區域受到影響。

不過,畢竟我認爲窗口更新請求是從另一個線程發送的。

使用GCD它看起來像這樣:

// Critical section ends here 
dispatch_async(dispatch_get_main_queue(), 
^{ 
    [affectedView setNeedsDisplay]; 
}); 

使用線程

// Critical section ends here 
[view performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];