KVO 区分 willChangeValueForKey 和 didChangeValueForKey - 两者都有必要吗?

2024-03-22

根据 Apple 自己的建议,在手动设置 KVC/KVO 兼容访问器时,应该包括BOTHKVO方法willChange and didChange。这就是我在所有手动访问器方法中所做的事情。

然而,observeValueForKeyPath:ofObject:change:contextKVC 方法的每一半(will 和 did)都会被调用exactly相同的字典内容。

使用以下选项注册观察者时:NSKeyValueObservingOptionPrior观察者still被调用两次 - 每半一次 - 并且,同样,具有相同的字典内容,仅保存键“notificationIsPrior”包含在字典中的差异。

现在,当 KVO 用于更改“CPU 昂贵”属性时(例如更改颜色或重新绘制大型且复杂的设计),只有对“didChange”进行操作并忽略(或至少分离出)“willChange”才有意义。 '。过去,我通过将密钥字符串转换为枚举列表元素来实现此目的,该元素返回左移“1”,并在收到第一个调用时使用该数字在 32 或 64 位整数中设置标志该标志在第二次重置,我执行 CPU 密集型操作。

然而,令我震惊的是,对于每种情况来说,这都是一个不小的开销。有没有人有任何其他“首选”方式来区分“willChange”的回调和“didChange”的回调,而不允许进行两次相同的处理?

我已经在苹果自己的文档和这个帮助小组中进行了大量的搜索,以寻找替代方案,但苹果自己的文档实际上并没有详细介绍这个主题,并且该小组中的几个人也遇到了类似的问题。在这两种情况下都没有提供明确的解决方案。如果有人知道更好的方法 - 除了使用交替标志来躲避“willChange”之外 - 我将非常感激。 (为什么苹果不能在更改字典中包含一个“阶段”键???)


我认为这就是您在评论中得到的内容,但为了未来的访问者的利益:

如果您想知道回调是“之前”还是“之后”,您可以在更改字典中查找 NSKeyValueChangeNotificationIsPriorKey 键。如果是事先通知,则该键将等于[NSNumber numberWithBool: YES](顺便说一句,字典也不会包含 NSKeyValueChangeNewKey 的值) NSKeyValueChangeNotificationIsPriorKey 的存在/值是权威的,因此,如果您在不期望的情况下看到它,则可能会收到双重回调。

如果您收到双重回调,听起来就像在 VectorVictors 的情况下一样,运行时正在触发它们并且您正在触发它们。如果您打算调用 will/didChangeValueForKey: 来手动管理您的 KVO 通知(并且您不想要双重通知),您应该实现以下类方法:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {

    BOOL automatic = NO;
    if ([theKey isEqualToString:@"propertyYourePlanningToManageYourself"]) {
        automatic = NO;
    } else {
        automatic=[super automaticallyNotifiesObserversForKey:theKey];
    }
    return automatic;
}

Apple对此有详细描述键值观察编程指南。 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html#//apple_ref/doc/uid/20002178-SW3

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

KVO 区分 willChangeValueForKey 和 didChangeValueForKey - 两者都有必要吗? 的相关文章

随机推荐