Re: Question about notifying KVO observers of changes to a property.
Re: Question about notifying KVO observers of changes to a property.
- Subject: Re: Question about notifying KVO observers of changes to a property.
- From: Ken Thomases <email@hidden>
- Date: Thu, 21 May 2009 20:34:34 -0500
On May 21, 2009, at 7:43 PM, Morales Vivó Óscar wrote:
On May 21, 2009, at 16:34 , Peter Duniho wrote:
On May 21, 2009, at 11:33 AM, Morales Vivó Óscar wrote:
I have an cocoa controller object with a property that is actually
read from another, C++ object. It works fine when updating or
reading the value, but sometimes other C++ parts of the program
will change the value of the property and there's no good way to
notify the cocoa controller object of the change.
I wanted to know if it's an issue from, elsewhere in the program,
just call the object's willChangeValueForKey: and
didChangeValueForKey: for a property that automatically notifies
when directly changed, or if there's a more immediate and
officially sanctioned way of letting an object know that it should
notify its observers that one of its properties has changed its
value.
Sorry if this is a silly question, but...
If you are able to call the associated KVO methods
(willChangeValueForKey:, didChangeValueForKey:), why can't you just
call the property setter?
I understand that if you've got data changing only within the C++,
propagating that back to the Obj-C object requires extra work. But
if you know when to call the KVO methods, surely you're already
propagating it somehow. Seems like you could at that point just
use the Obj-C object's setter instead of setting it internally to
the C++ and calling the KVO methods directly.
Good point. The problem I'm having is that I don't know when to call
the "willChange…" method, only that sometimes I need to call the
"didChange…" one.
If you're asking if you can just call willChange... and then
immediately call didChange..., both being called after the value has
changed, then that's tricky and error prone. You shouldn't do it.
Calls to willChange... and didChange... should really bracket the
actual change in value of the property.
KVO can request the value of the property during willChange... and
during didChange... It can cache the "old" value and use it and the
new value during didChange... If the cached "old" value isn't
actually old but new, because willChange... was actually called after
the property changed, then it can break things. For example, KVO may
attempt to remove observations of key subpaths from the old value
during didChange..., but it's removing those observations from the
wrong thing because it doesn't really have the old value.
One approach is to modify your C++ code to provide your Objective-C
code an opportunity to call willChange... before the value actually
changes. It may not be appropriate for the C++ object to know about
the Objective-C wrapper around it. That is, you may not want tight
coupling there. You can use a loosely couple technique like the
Notification design pattern.
Another approach is to make your Objective-C wrapper duplicate the
data of the C++ object, rather than being a pass-through wrapper. So,
the getter for the property on your Objective-C wrapper does _not_
call through to C++ object to get the current value. Instead, it
returns a cached value. Since your C++ code apparently already
provides a post-change notification (or can easily be made to do so),
your Objective-C code would only change its cached copy when it
receives that notification. At that time, it can use a standard KVO-
compliant setter to change its cached copy of the property value, or
it can do willChange..., update the cache, didChange...
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden