Re: Binding and multithreading
On Mar 24, 2012, at 10:46 AM, Jonathan Taylor wrote: It sounds, though, as if it should be ok to use observeValueForKeyPath:ofObject:change:context (which will run on the secondary thread, by the sound of it) as a way of monitoring the fact that "something" has changed in the state of my object. I can then use that as a single place in which I schedule a GUI update via a shadow object on the main thread. Does that sound as if it would be ok? The Cocoa Design Patterns chapter of the Cocoa Fundamentals Guide (which I didn't read well enough) has a general solution (a receptionist object). If you just want to call a method of the observing object on the main thread then performSelectorOnMainThread may be all you need. Jan E. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Binding and multithreading
On Mar 24, 2012, at 2:46 AM, Jonathan Taylor wrote: > It sounds, though, as if it should be ok to use > observeValueForKeyPath:ofObject:change:context (which will run on the > secondary thread, by the sound of it) as a way of monitoring the fact that > "something" has changed in the state of my object. I can then use that as a > single place in which I schedule a GUI update via a shadow object on the main > thread. Does that sound as if it would be ok? Yes. The -observeValue… method will be called on whatever thread the property changed on; as long as the method does the scheduling in a thread-safe way, it’ll be fine. (For example, I believe calling -[NSView setNeedsDisplay:] is thread-safe.) This doesn’t really help solve the OP’s issue — it’s very convenient to use bindings instead of direct observation, as you don’t have to write code; but this gives you no opportunity to reschedule onto the main thread. Maybe it would be possible to implement a generic proxy object that could be interposed, and relay the property-change notifications from one thread to another. I don’t think this would allow easy wiring up of bindings from IB, though. —Jens ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Binding and multithreading
Hi Jonathan, Yes, that would work as long as the thing that changed is KVO compliant. To update the shadow object, you can do as Jens suggested, or use dispatch_async to the main thread, or use the main operation queue as described in the receptionist pattern. Cheers, Dave On 2012-03-24, at 5:46 AM, Jonathan Taylor wrote: > It sounds, though, as if it should be ok to use > observeValueForKeyPath:ofObject:change:context (which will run on the > secondary thread, by the sound of it) as a way of monitoring the fact that > "something" has changed in the state of my object. I can then use that as a > single place in which I schedule a GUI update via a shadow object on the main > thread. Does that sound as if it would be ok? > > On 23 Mar 2012, at 23:14, Dave Fernandes wrote: > >> See the Cocoa Design Patterns doc: >> "The Receptionist Design Pattern in Practice >> A KVO notification invokes the >> observeValueForKeyPath:ofObject:change:context: method implemented by an >> observer. If the change to the property occurs on a secondary thread, >> theobserveValueForKeyPath:ofObject:change:context: code executes on that >> same thread." >> >> So you shouldn't use observeValueForKeyPath:ofObject:change:context to >> update the GUI in this context. I don't know of any better method than what >> the OP suggested. >> >> Cheers, >> Dave >> >> On 2012-03-23, at 6:32 PM, Jan E. Schotsman wrote: >> >>> Jonathan Taylor wrote: I have been struggling with a problem which I think I have eventually realised is down to me not handling multithreading issues properly. The situation is I have some computationally-demanding code that is running in a separate thread. This has input parameters and state variables associated with it. For diagnostic reasons I would like to be able to display the values of the state variables in the GUI. I had intended to do this just by binding to them. However I am getting occasional "message sent to deallocated instance" errors which I suspect are a symptom of the fact that I am Doing It Wrong. Further reading suggests that because of the way bindings work, modifying those state variables is leading to binding/gui type stuff happening away from the main thread, which appears not to be permitted. >>> I use KVO for this. Have your main thread observe the state variables >>> (declared as properties) and update the GUI in your >>> observeValueForKeyPath:ofObject:change:context: method. >>> I hope this is elegant enough for you ;-) >>> Jan E. >>> ___ >>> >>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >>> >>> Please do not post admin requests or moderator comments to the list. >>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >>> >>> Help/Unsubscribe/Update your Subscription: >>> https://lists.apple.com/mailman/options/cocoa-dev/dave.fernandes%40utoronto.ca >>> >>> This email sent to dave.fernan...@utoronto.ca >> > ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Binding and multithreading
It sounds, though, as if it should be ok to use observeValueForKeyPath:ofObject:change:context (which will run on the secondary thread, by the sound of it) as a way of monitoring the fact that "something" has changed in the state of my object. I can then use that as a single place in which I schedule a GUI update via a shadow object on the main thread. Does that sound as if it would be ok? On 23 Mar 2012, at 23:14, Dave Fernandes wrote: > See the Cocoa Design Patterns doc: > "The Receptionist Design Pattern in Practice > A KVO notification invokes the > observeValueForKeyPath:ofObject:change:context: method implemented by an > observer. If the change to the property occurs on a secondary thread, > theobserveValueForKeyPath:ofObject:change:context: code executes on that same > thread." > > So you shouldn't use observeValueForKeyPath:ofObject:change:context to update > the GUI in this context. I don't know of any better method than what the OP > suggested. > > Cheers, > Dave > > On 2012-03-23, at 6:32 PM, Jan E. Schotsman wrote: > >> Jonathan Taylor wrote: >>> I have been struggling with a problem which I think I have eventually >>> realised is down to me not handling multithreading issues properly. The >>> situation is I have some computationally-demanding code that is running in >>> a separate thread. This has input parameters and state variables associated >>> with it. For diagnostic reasons I would like to be able to display the >>> values of the state variables in the GUI. I had intended to do this just by >>> binding to them. However I am getting occasional "message sent to >>> deallocated instance" errors which I suspect are a symptom of the fact that >>> I am Doing It Wrong. Further reading suggests that because of the way >>> bindings work, modifying those state variables is leading to binding/gui >>> type stuff happening away from the main thread, which appears not to be >>> permitted. >> I use KVO for this. Have your main thread observe the state variables >> (declared as properties) and update the GUI in your >> observeValueForKeyPath:ofObject:change:context: method. >> I hope this is elegant enough for you ;-) >> Jan E. >> ___ >> >> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >> >> Please do not post admin requests or moderator comments to the list. >> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >> >> Help/Unsubscribe/Update your Subscription: >> https://lists.apple.com/mailman/options/cocoa-dev/dave.fernandes%40utoronto.ca >> >> This email sent to dave.fernan...@utoronto.ca > ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Binding and multithreading
On Mar 23, 2012, at 3:32 PM, Jan E. Schotsman wrote: > I use KVO for this. Have your main thread observe the state variables > (declared as properties) and update the GUI in your > observeValueForKeyPath:ofObject:change:context: method. That’s just going to call observeValue… on whatever thread the model state property changed on, not on the main thread. Which is exactly what the OP is asking how to avoid. I don’t have an easy answer, other than implementing an observeValue… method that uses performSelector:onThread: to defer the real work to the main thread. —Jens smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Binding and multithreading
See the Cocoa Design Patterns doc: "The Receptionist Design Pattern in Practice A KVO notification invokes the observeValueForKeyPath:ofObject:change:context: method implemented by an observer. If the change to the property occurs on a secondary thread, theobserveValueForKeyPath:ofObject:change:context: code executes on that same thread." So you shouldn't use observeValueForKeyPath:ofObject:change:context to update the GUI in this context. I don't know of any better method than what the OP suggested. Cheers, Dave On 2012-03-23, at 6:32 PM, Jan E. Schotsman wrote: > Jonathan Taylor wrote: >> I have been struggling with a problem which I think I have eventually >> realised is down to me not handling multithreading issues properly. The >> situation is I have some computationally-demanding code that is running in a >> separate thread. This has input parameters and state variables associated >> with it. For diagnostic reasons I would like to be able to display the >> values of the state variables in the GUI. I had intended to do this just by >> binding to them. However I am getting occasional "message sent to >> deallocated instance" errors which I suspect are a symptom of the fact that >> I am Doing It Wrong. Further reading suggests that because of the way >> bindings work, modifying those state variables is leading to binding/gui >> type stuff happening away from the main thread, which appears not to be >> permitted. > I use KVO for this. Have your main thread observe the state variables > (declared as properties) and update the GUI in your > observeValueForKeyPath:ofObject:change:context: method. > I hope this is elegant enough for you ;-) > Jan E. > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/dave.fernandes%40utoronto.ca > > This email sent to dave.fernan...@utoronto.ca ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Binding and multithreading
Jonathan Taylor wrote: I have been struggling with a problem which I think I have eventually realised is down to me not handling multithreading issues properly. The situation is I have some computationally-demanding code that is running in a separate thread. This has input parameters and state variables associated with it. For diagnostic reasons I would like to be able to display the values of the state variables in the GUI. I had intended to do this just by binding to them. However I am getting occasional "message sent to deallocated instance" errors which I suspect are a symptom of the fact that I am Doing It Wrong. Further reading suggests that because of the way bindings work, modifying those state variables is leading to binding/ gui type stuff happening away from the main thread, which appears not to be permitted. I use KVO for this. Have your main thread observe the state variables (declared as properties) and update the GUI in your observeValueForKeyPath:ofObject:change:context: method. I hope this is elegant enough for you ;-) Jan E. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Binding and multithreading
I have been struggling with a problem which I think I have eventually realised is down to me not handling multithreading issues properly. The situation is I have some computationally-demanding code that is running in a separate thread. This has input parameters and state variables associated with it. For diagnostic reasons I would like to be able to display the values of the state variables in the GUI. I had intended to do this just by binding to them. However I am getting occasional "message sent to deallocated instance" errors which I suspect are a symptom of the fact that I am Doing It Wrong. Further reading suggests that because of the way bindings work, modifying those state variables is leading to binding/gui type stuff happening away from the main thread, which appears not to be permitted. What I can't work out is whether there is a reasonably elegant and uncomplicated way of achieving what I want: the properties in question are being modified from a secondary thread, and I would like to display their values in the GUI, preferably via bindings for convenience. I could for example keep a "shadow object" which the GUI binds to, whose state is updated either periodically or in specific response to changes to properties in the primary object based in the secondary thread. However that strikes me as rather unwieldy and requiring a fair amount of extra code to implement correctly and efficiently. I feel there must be a better way of dealing with my problem - or maybe there isn't, and I just need to accept that bindings etc do not work well in a multithreaded environment. Does anybody have any advice? Cheers Jonny ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com