ios - KVO 区分 willChangeValueForKey 和 didChangeValueForKey - 两者都是必要的吗?

标签 ios callback key-value-observing key-value-coding

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

但是,observeValueForKeyPath:ofObject:change:context 会针对具有完全相同字典内容的 KVC 方法的每一半(will 和 did)进行调用。

当使用选项注册一个观察者时:NSKeyValueObservingOptionPrior 观察者仍然被调用两次——每一半一次——并且再次使用相同的字典内容,保存唯一的区别是键“notificationIsPrior”包含在字典中。

现在,当 KVO 用于改变“CPU 消耗大”的属性时——比如改变颜色或重新绘制大型精心设计的设计时,只对“didChange”采取行动并忽略(或至少分开)才有意义'willChange'。过去,我通过将 key 字符串转换为枚举列表元素来实现这一点,该元素返回左移的“1”,并在收到第一次调用时使用该数字将标志设置为 32 或 64 位整数标志在第二个重置,我执行 CPU 密集型操作。

但是,令我印象深刻的是,对于每个案例来说,这都是一项非常重要的开销。有没有人有任何其他“首选”方式来区分“willChange”的回调和“didChange”的回调,而不允许两次执行相同的处理?

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

最佳答案

我认为这就是您在评论中的意思,但为了 future 访问者的利益:

如果您想知道回调是“之前”还是“之后”,您可以在更改字典中查找 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 的 Key-Value Observing Programming Guide. 中有详细描述。

关于ios - KVO 区分 willChangeValueForKey 和 didChangeValueForKey - 两者都是必要的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8399715/

相关文章:

angularjs - ngAnimate,addClass 回调在动画结束后不运行

ios - 这个 observeValueForKeyPath 有什么问题 :ofObject:change:context: implementation?

ios - 键值观察的新手;为什么我无法在我的 AppDelegate 中监控 int 的值?

javascript - 获取并检查 NodeJS 中读取的 JSON 值

objective-c - 如何检测 Objective-C 中的属性返回类型

ios - 有没有办法在 iOS 应用程序的 VoiceOver 中更改默认辅助功能操作的文本?

ios - tableView.insertRows 抛出 NSException,但不是当 `insertRows` at `[[0,0]]`

ios - 出现 View 时立即打开相机

ios - Xamarin.Forms ListView 单元重用?

Javascript,addEventListener 回调函数立即执行并且只执行一次?