【问题标题】:KVO notification not sent when using the super class' setter使用超类的设置器时未发送 KVO 通知
【发布时间】:2014-07-15 14:17:33
【问题描述】:

我有一个定义属性的 ClassA:

@interface ClassA : NSObject
@property (nonatomic) CGPoint property;
@end

实现不会覆盖访问器。

ClassB 会覆盖 setter 来做一些额外的工作:

- (void)setProperty:(CGPoint)property {
    [super setProperty:property];
    [self someAdditionalWork];
}

在 ClassB 的另一种方法中,我尝试通过超级设置器设置此属性,以跳过额外的工作:

- (void)otherMethodInClassB {
    // ...
    super.property = newValue;
    // ...
}

当我这样做时,不会发送属性的 KVO 通知。如果我做同样的事情,但使用self,KVO 通知会按预期工作:

- (void)otherMethodInClassB {
    // ...
    self.property = newValue;
    // ...
}

这里发生了什么?这是预期的行为吗?我找不到任何可以这么说的东西。

【问题讨论】:

  • 该属性不应该有assign 属性吗?
  • @trojanfoe 这不是原语的默认设置吗?
  • 是的,你可能是对的 :)

标签: objective-c key-value-observing kvc


【解决方案1】:

我不确定这是否记录在案,但这是预期的行为。

自动 KVO 通知通过在运行时静默地将实例的类从原始 ClassB 更改为自动生成的子类 NSKVONotifying_ClassB 来工作,它会覆盖所有必需的 setter 方法来为您执行那些 willChange.../didChange... 调用。通过调用 super,你可以有效地跳过所有的魔法并调用原始的 setter,它只进行简单的赋值。

附:这篇博文深入探讨了这一点:https://www.mikeash.com/pyblog/friday-qa-2009-01-23.html

【讨论】:

  • 嗯,很有趣。但是超级二传手不也被悄悄改变了吗?有没有推荐的方法来解决这个问题?我应该在 ClassB 中停用自动 KVO 并在我的 setter 中添加 will/didChange 调用吗?
  • super 调用仍然调用原始超类,或者当然,就像 classclassName 这样的方法一直假装什么都没发生——可能还有更多怪癖,我不确定.解决您的情况的最简单方法是在调用super 周围手动调用willChange.../didChange...。如果不知道您要完成什么,我无法提供更好的建议,但是这样的问题可能表明您需要重新考虑您的类设计和/或实现。
猜你喜欢
  • 2013-01-30
  • 2019-10-13
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
相关资源
最近更新 更多