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

时间:2011-12-06 12:15:27

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

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

但是,observeValueForKeyPath:ofObject:change:context会在完全相同的词典内容中为每一半KVC方法(将要做的)调用NSKeyValueObservingOptionPrior

当使用选项{{1}}注册观察者时,观察者仍然被调用两次 - 每半次一次 - 并且再次使用相同的字典内容,只保存差异密钥' notificationIsPrior'包含在字典中。

现在,当KVO被用来改变CPU价格昂贵的'属性 - 比如改变颜色或重新绘制一个大而精致的设计,只有采取行动才能做出改变。并忽略(或至少分开)' willChange'。在过去,我通过将键字符串转换为枚举列表元素来实现此目的,该元素返回左移的' 1'并且在接收到第一个调用时使用该数字设置32或64位整数的标志,并且当第二个调用时重置标志时,执行CPU密集型操作。

然而,令我感到震惊的是,对于每个案例来说,这都是一个非常重要的开销。有没有人有任何其他的首选'区分' willChange'的回调方式。而那就是“改变了”#39;不允许两次相同的处理?

我已经仔细搜索过苹果自己的文档和这个帮助小组,因为苹果公司自己的文档实际上并没有详细介绍这个主题,而且这个小组中的一些人也有与类似的担忧搏斗。在任何情况下都没有提供确定的解决方案。如果有人知道更好的方式 - 除了躲避' willChange'使用交替的旗帜 - 我非常感激。 (为什么Apple不能在更改字典中包含一个'阶段的键?)

1 个答案:

答案 0 :(得分:5)

我认为这是你在评论中所得到的,但为了未来访客的利益:

如果要判断回调是“之前”还是“之后”,您可以在更改字典中查找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.

中有详细描述