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

Reply via email to