2016-11-21 74 views
4

我試圖從背景操作中繪製到NSView,但沒有看到任何效果。從後臺操作中繪製NSView不起作用

let queue = OperationQueue() 
queue.addOperation() { 
    doTheBackgroundStuff() 
} 

開始後臺操作,它正在做大量的計算。在AppDelegate中我有

@IBOutlet weak var image: NSImageView! // some image to show 
@IBOutlet weak var number: NSTextField! // a corresponding number 
@IBOutlet weak var mainView: NSView! // the main view holding the above 

分配

number.intValue = Int32(someNumber) 

從後臺操作發行的定期(通常)。但文字永遠不會改變。我在IB中爲視圖和TextField設置了「可同時繪製」。我也試過

if mainView.lockFocusIfCanDraw() { 
    mainView.setNeedsDisplay(mainView.rectPreservedDuringLiveResize) 
    mainView.unlockFocus() 
} 

之後的文本字段分配。也無濟於事。

+0

執行到達'if mainView.lockFocusIfCanDraw(){...}'的內部嗎? –

+0

@ l'L'l是的,它的確如此。 –

+0

您可能想要顯示您用來更新文本字段的代碼。 –

回答

2

通常這些問題消失,如果你從你的後臺任務內將您的視圖更新代碼回到主隊列:

DispatchQueue.main.async { 
    // your view update code 
} 

如果不是裏面你doTheBackgroundStuff你可以只撒了太多的地方那些在查看更新,即每當你訪問你的mainView

否則,它有助於將事物重新分組爲非UI重組的部分,然後在最後將視圖更新推送到Dispatch.main.async

+0

那種作品。我可以看到現在田地在變化。但是它的速度慢得像糖漿。可能整個開窗並不是按照我所需要的那種大規模更新而設計的。 –

+0

我建議將更新合併到以合理間隔刷新的組中。如果你的更新適合這些,你甚至可以順利地在它們之間轉換。如果讓UIView在兩個狀態之間執行動畫,則會比試圖頻繁推送更新的結果更平滑。 – sas

+0

是的,可能會讓它更平滑。但是這需要我找到一種緩衝更新的巧妙方式(每秒25個)。一個簡單的計時器可能會完成這項工作。 –

3

呼叫flushGraphicshttps://stackoverflow.com/a/19997698/3419541描述:

我在Thread guide瞭解NSGraphicsContext限制。

在這裏,我發現了以下行:

如果任何從輔助線程繪畫,你必須刷新你的 繪圖手動調用。 可可不會自動更新與 內容視圖從輔助線程繪製,所以你需要調用獲取到NSGraphicsContext的 flushGraphics方法,當你完成你的 圖。 如果您的應用程序僅從主線程中提取內容,則您不需要刷新繪圖調用。

+0

我試過'NSGraphicsContext(window:window!)。flushGraphics()'在鎖部分。不用找了。 –

+0

這會給你一個新的圖形上下文,你需要[與你的窗口關聯的](https://developer.apple.com/reference/appkit/nswindow/1419713-graphicscontext)。一定要從主線程中檢索,GraphicsContexts是線程本地的。 – CodaFi

+0

當我將此添加到我的代碼中時,出現'_initWithWindowNumber:錯誤,爲ctx'創建圖形ctxt對象錯誤。 –