Try overriding +[NSObject(NSKeyValueObserving) automaticallyNotifiesObserversForKey:] to return NO for the properties you want to handle manually.
On 2012-01-16, at 01:30, Gideon King wrote: > Hi all, when I declare a property, something like: > > @property(readwrite, copy, nonatomic) NSString *foo; > > I will synthesize it with: > > @synthesize foo; > > But then I want to do some special processing when the value is set, so I > implement my setter: > > - (void)setFoo:(NSString *)aFoo { > [self willChangeValueForKey:@"foo"]; > [foo autorelease]; > foo = [aFoo retain]; > [self didChangeValueForKey:@"foo"]; > [self > doSomeMoreProcessingThatShouldHappenAfterAllTheObserversKnowTheNewValue]; > } > > I assumed from the documentation and examples that since I was providing my > own implementation method, that I would have to include the willChange and > didChange methods at appropriate points in my code, but I have just > discovered that when I do: > > anObject.foo = @"something"; > > I get two prior notifications - one from the internals of the system, and one > from my willChange call, and two notifications after the change - one from my > didChange and one from the system. > > So I thought this must because I used @synthesize as well as providing my own > method, so I implemented a getter and removed the @synthesize. The behavior > didn't change. > > I double checked this by removing my willChange and didChange methods, and > now the prior and after notifications only got sent once. > > One purpose of mentioning this is that given the fact that I have come across > code from several places where they did what I did and had the willChange and > didChange code in their setters, others may need to look back at their code > and make appropriate changes. > > But the big thing for me is that I have a number of places throughout my > application where I need to have the changes made, the didChange notification > acted on by the observers, and then some other code run. > > I therefore wanted to use the setter, but not have to change the name of it, > so that bindings would still work, so I changed my property declaration to be > readonly, and declared a setFoo: method. I thought that declaring it would > make it not call the willChange and didChange behind the scenes, but > unfortunately, even with a readonly declaration, when I used anObject.foo = > @"something", it still called the prior and after KVO methods. So I thought I > would explicitly call setFoo: instead of using dot notation, but that made no > difference. On the off chance there was something else going on, I also > turned off accessesInstanceVariablesDirectly, but that made no difference. > > So I thought I would just remove the property declarations altogether, and > just code my accessors myself, but it still called the built in KVO methods. > > Therefore my conclusion is that as soon as you add a KVO observation on > anything, it triggers the prior and after notifications whenever the setter > is called. This of course makes sense, but still leaves me with the original > problem: I need some way to have the KVO notifications called *once only*, > and yet have my setters able to call other methods after the KVO > notifications have been sent. It is not possible for this to be done with > performSelector:withObject:afterDelay: or anything similar, since these > methods need to be called immediately after the after change notification. > > I know I could get it to call the KVO notifications at only the right places > by coding my own methods like -(void)changeFooTo:, but I do not want to > change the name of my setters because that would break my bindings. > > Are there any recommendations on the best approach for being able to have the > setter able to do what it needs with the KVO and then calling other methods, > without breaking bindings? > > I can't believe I have misunderstood this for so long, and never noticed what > was happening until now! > > Thanks > > Gideon > > > > > > > > > _______________________________________________ > > 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: > http://lists.apple.com/mailman/options/cocoa-dev/gordonhenriksen%40me.com > > This email sent to gordonhenrik...@me.com _______________________________________________ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com