views:

313

answers:

2

I've got a window which reflects the status of an NSOperation. How should I bind the NSProgressIndicator to the NSOperation's progress-property?

+4  A: 

AppKit is not thread-safe. Any updates to a UI object must happen on the main thread. KVO doesn't dispatch observation messages across threads. So you'll need and another way of updating the progress indicator than just plain KVO.

In your NSOperation's main method, you'll need to dispatch progress messages periodically. The easiest thing to do would be to use NSNotificationCenter with a custom notification so that the main thread can listen for the updates. (Note that notifications are always delivered on the thread from which they were sent, so you'll need to use the performSelectorOnMainThread: method to make sure the notifications are delivered on the UI thread.)

In your main thread, you'll need to add your class as an observer to receive those notifications and update the progress indicator. If you want to use bindings for the progress indicator, you can bind it to a property on your controller object that you update when you receive progress notifications from the NSOperation.

Alex
In general, this is correct, but updates to NSProgressIndicator are specifically documented as being threadsafe.
Barry Wark
@Barry Wark: Have you gotten a link, I haven't found anything in the documentation.
Georg
Could I also use `perfomSelectorOnMainThread:` in response to a KVO message?
Georg
I haven't seen anything about NSProgressIndicator being thread safe, either... So your `NSOperation` would do something that triggers a KVO notification? Assuming whatever your operation does is thread-safe, you should be able to call performSelectorOnMainThread: in response to the KVO message. However, I'd recommend that the KVO handler do nothing but call performSelectorOnMainThread:, otherwise you'll end up with a recipe for all kinds of thread-related nastiness. Just be careful and you should be OK.
Alex
A: 

Ben Copsey's ASIHTTPRequest wrappers do exactly this sort of thing.

The request is a subclass of NSOperation, and you can pass it a progress indicator when instantiated.

The code is available for you to look at, if you wanted to see how it works.

Alex Reynolds
As far as I see it this violates the MVC pattern…
Georg