views:

204

answers:

3

I saw these lines in a demo project, but I couldn't understand why it did that.

[self willChangeValueForKey:@"names"];
[self didChangeValueForKey:@"names"];

It called didChangeValueForKey immediately after willChangeeValueForKey. Does it make any sense?

Furthermore, when should be the right time to call this two methods? Thanks a lot!! :)

A: 
  • If you want to do stuff just before the value gets changed, use willChangeValueForKey.
  • If you want to do stuff just after the value gets changed, use didChangeValueForKey.

Edit: ignore me, was reading too fast - Barry is right :-)

Mike Howard
+1  A: 

Those have to do with manually controlling key value observing. Normally the system takes care of it but these allow you some control. Look at this documentation to understand when and how to use them here.

regulus6633
+2  A: 

This is, in fact, an anti-pattern. You should not call -willChangeValueForKey: followed by -didChangeValueForKey: without any intervening actual property change. In some cases, doing so can mask KVO problems elsewhere in your code and force observers to update their state related to the property in question. Ultimately, however, you (or the author of the example you cite) should fix the rest of the code so that this anti-pattern is unnecessary.

The correct usage of -will|didChangeValueForKey: is when you are modifying a property without using KVC-compliant accessors/setters such that the KVO mechanism would not notice the change. For a contrived example, consider modifying the backing instance variable for an attribute directly:

@interface Foo
{
   int bar;
}
@end

@implementation Foo
- (void)someMethod
{
  bar = 10;
}
@end

KVO observers that had registered for notification of changes in the bar property would not recieve notification of the change to bar in -someMethod. To make the KVO machinery work, you could modify -someMethod:

- (void)someMethod
{
  [self willChangeValueForKey:@"bar"];
  bar = 10;
  [self didChangeValueForKey:@"bar"];
}

Of course, it would be better to use a @property declaration and to use KVC-compliant accessors/setters (either manually coded or @synthesized), but this is a contrived example.

Barry Wark
Thank you so much!
Frost