从后台操作在 NSView 中绘制无效

Drawing in NSView from background operation has no effect

我正在尝试从后台操作绘制到 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 设置了 "can draw concurrently"。我也试过了

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

在文本字段分配之后。也没用。

如所述调用flushGraphics

I read about NSGraphicsContext Restriction at Thread guide.

Here, I found the following line:

If you do any drawing from a secondary thread, you must flush your drawing calls manually. Cocoa does not automatically update views with content drawn from secondary threads, so you need to call the flushGraphics method of NSGraphicsContext when you finish your drawing. If your application draws content from the main thread only, you do not need to flush your drawing calls.

如果您从后台任务中将视图更新代码发送回主队列,通常这些问题就会消失:

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

如果您的 doTheBackgroundStuff 中没有太多地方,您可以将它们撒在视图更新中,即每当您访问 mainView.

否则,它有助于将事物重新分组到执行非 UI 繁重工作的部分,然后将视图更新推送到最后的 Dispatch.main.async