Should I use will/didSetValueForKey inside a custom setter?

Possible Duplicate:
Receiving 2 KVO notifications for a single KVC change

I'm confused about where I should be using willChangeValueForKey: and didChangeValueForKey: .

I have an object with a property which requires a custom setter method. As per the Apple documentation, I am using will/didChangeValueForKey: :

To implement manual observer notification, you invoke willChangeValueForKey: before changing the value, and didChangeValueForKey: after changing the value. The example in Listing 3 implements manual notifications for the openingBalance property.

Listing 3 Example accessor method implementing manual notification

- (void)setOpeningBalance:(double)theBalance {
    [self willChangeValueForKey:@"openingBalance"];
    _openingBalance = theBalance;
    [self didChangeValueForKey:@"openingBalance"];
}

This makes my object look something like the below:

@interface cObject
@property (readwrite, nonatomic) BOOL Property;
@end

@implementation cObject
- (void)setProperty:(BOOL)Property
{
   [self willChangeValueForKey:@"Property"];
   _Property = Property;
   [self didChangeValueForKey:@"Property"];
   //Do some other stuff
}
@end

The source of my confusion is that if I set up another object to observe Property on an instance of cObject and then call [myObject setProperty:] , my observer's callback function is hit twice . Looking at the stack: the first hit happens as a result of me calling didChangeValueForKey: , the second hit is a direct result of me calling setProperty: (ie my custom setter does not appear in the stack).

To further add to the confusion, if I change _Property in another function elsewhere in cObject , my observer will not be notified (unless I use did/willChangeValueForKey: , of course!).

EDIT: Even if I do not change _Property in my custom setter, KVO notifies my observer that it has changed. From this, I conclude that KVO is being invoked as just a result of me calling the setter, regardless of whether anything changes or not...

Can anybody explain how my situation differs from that explained in the documentation?


From the docs. If you want manual, you have to override that:

Manual Change Notification

Manual change notification provides more granular control over how and when notifications are sent to observers. This can be useful to help minimize triggering notifications that are unnecessary, or to group a number of changes into a single notification.

A class that implements manual notification must override the NSObject implementation of automaticallyNotifiesObserversForKey:. It is possible to use both automatic and manual observer notifications in the same class. For properties that perform manual notification, the subclass implementation of automaticallyNotifiesObserversForKey: should return NO. A subclass implementation should invoke super for any unrecognized keys. The example in Listing 2 enables manual notification for the openingBalance property allowing the superclass to determine the notification for all other keys.

链接地址: http://www.djcxy.com/p/47346.html

上一篇: 无法更新嵌套的NSMutableDictionary

下一篇: 我应该在自定义setter中使用will / didSetValueForKey吗?