Re: KVO willChange and didChange
Re: KVO willChange and didChange
- Subject: Re: KVO willChange and didChange
- From: Roland King <email@hidden>
- Date: Mon, 16 Jan 2012 14:39:18 +0800
Read the section Automatic Change Notification again and understand it has nothing to do with properties or dot notation but just the method name.
Then look up automaticallyNotifiesObserversForKey and turn it off if you want to code one key fully manually.
On 16 Jan, 2012, at 14:30, Gideon King <email@hidden> 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 (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
_______________________________________________
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