Reputation: 36305
I'm trying to draw to a NSView
from a background operation, but don't see any effect.
let queue = OperationQueue()
queue.addOperation() {
doTheBackgroundStuff()
}
starts the background operation, which is doing lots of calculations. In the AppDelegate I have
@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
The assignment
number.intValue = Int32(someNumber)
is issued from the background operation regularly (often). But the text does never change. I have set the "can draw concurrently" in IB for the view as well as for the TextField. I also tried
if mainView.lockFocusIfCanDraw() {
mainView.setNeedsDisplay(mainView.rectPreservedDuringLiveResize)
mainView.unlockFocus()
}
after the text field assignment. Also to no avail.
Upvotes: 4
Views: 697
Reputation: 7542
Typically these problems go away if you send your view updating code back to the main queue from within your background task:
DispatchQueue.main.async {
// your view update code
}
If there's not too many place inside your doTheBackgroundStuff
you could just sprinkle those in for view updates, i.e. whenever you access your mainView
.
Otherwise it helps to re-group things into parts that do non-UI heavy lifting and then push the view updates to Dispatch.main.async
at the end.
Upvotes: 2
Reputation: 1536
Call flushGraphics
as described in https://stackoverflow.com/a/19997698/3419541:
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.
Upvotes: 3