【发布时间】:2013-01-04 13:44:23
【问题描述】:
我对应该在哪里使用 willChangeValueForKey: and didChangeValueForKey: 感到困惑。
我有一个需要自定义设置方法的属性的对象。根据the Apple documentation,我正在使用will/didChangeValueForKey::
要实现手动观察者通知,您可以在更改值之前调用 willChangeValueForKey:,在更改值之后调用 didChangeValueForKey:。清单 3 中的示例实现了 openingBalance 属性的手动通知。
清单 3 实现手动通知的示例访问器方法
- (void)setOpeningBalance:(double)theBalance { [self willChangeValueForKey:@"openingBalance"]; _openingBalance = theBalance; [self didChangeValueForKey:@"openingBalance"]; }
这使我的对象如下所示:
@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
我困惑的根源是,如果我在cObject 的实例上设置另一个对象来观察Property,然后调用[myObject setProperty:],我的观察者的回调函数会被点击两次。查看堆栈:第一次命中是我调用didChangeValueForKey: 的结果,第二次命中是我调用setProperty: 的直接结果(即我的自定义设置器没有出现在堆栈中)。
为了进一步增加混乱,如果我在 cObject 其他地方的另一个函数中更改 _Property,我的观察者将不会收到通知(除非我使用 did/willChangeValueForKey:,当然!) .
编辑:即使我没有更改自定义设置器中的_Property,KVO 也会通知我的观察者它已更改。由此,我得出结论,KVO 被调用只是因为我调用了 setter,而不管是否有任何变化......
谁能解释我的情况与文档中解释的情况有何不同?
【问题讨论】:
-
你确定同一个对象被击中两次吗?也许单个对象的多个观察者?还是一个观察者注册了两次?
-
@FernandoMazzon:是的,它是同一个对象,不,它不是双重注册的观察者——这是我最初的想法,但创建了一个人为的例子(我可以确定这两种可能性可以打折)导致相同的结果。
-
顺便说一句,您应该参考Code Naming Basics 了解命名约定。类应以大写字母开头。带有小写字母的属性。
-
@Rob:同意 - 并为该文档 +1。然而,我们的团队主要是 C++,并且我们有我们必须遵循的历史命名约定:-/
标签: objective-c ios ios6 key-value-observing