【问题标题】:Should I use will/didSetValueForKey inside a custom setter? [duplicate]我应该在自定义设置器中使用 will/didSetValueForKey 吗? [复制]
【发布时间】:2013-01-04 13:44:23
【问题描述】:

可能重复:
Receiving 2 KVO notifications for a single KVC change

我对应该在哪里使用 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


【解决方案1】:

来自文档。如果你想要手动,你必须覆盖它:

手动更改通知

手动更改通知可以更精细地控制如何和 当通知发送给观察者时。这对帮助很有用 尽量减少不必要的触发通知,或将 单个通知中的更改数量。

实现手动通知的类必须重写 NSObject automaticNotifiesObserversForKey: 的实现。这是 可以使用自动和手动观察者通知 同一个班级。对于执行手动通知的属性, automaticNotifiesObserversForKey 的子类实现: 应该返回 NO。子类实现应该调用 super for 任何无法识别的键。清单 2 中的示例启用手动 允许超类的 openingBalance 属性的通知 确定所有其他键的通知。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多