KVO区分willChangeValueForKey和didChangeValueForKey - 都是必要的? [英] KVO differentiating between willChangeValueForKey and didChangeValueForKey - are both necessary?

查看:3143
本文介绍了KVO区分willChangeValueForKey和didChangeValueForKey - 都是必要的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In line with Apple's own recommendations, when setting KVC/KVO compliant accessors manually, one should include BOTH KVO methods willChange and didChange. This is what I have done in all my manual accessor methods.

但是, observeValueForKeyPath:ofObject:change:context 被调用的每一半的KVC方法(will和did)用完全相同的字典内容。

However, observeValueForKeyPath:ofObject:change:context gets called for each half of the KVC methods (will and did) with exactly the same dictionary contents.

在使用选项注册观察者时: NSKeyValueObservingOptionPrior 观察者 - 对于每一半一次,并且同样地,对于相同的字典内容,仅保存键notificationIsPrior被包括在字典中的差别。

When registering an observer using the option: NSKeyValueObservingOptionPrior the observer still gets called twice - once for each half - and, again, with identically the same dictionary contents, save only the difference that the key 'notificationIsPrior' is included in the dictionary.

现在,当KVO用于改变CPU昂贵属性时,例如更改颜色或重绘大型精致的设计, 'didChange'并忽略(或至少单独出来)'willChange'。在过去,我已经实现了这一点,通过将密钥字符串转换为枚举列表元素返回一个左移1,并使用这个数字设置一个32或64位整数的标志,当收到第一个调用,标志在第二次复位,我执行CPU密集型操作。

Now, when KVO is used to alter 'CPU-expensive' attributes - like changing a colour or redrawing a large and elaborate design, it makes sense only to act on the 'didChange' and ignore (or at least separate out) the 'willChange'. In the past, I have achieved this by converting the key string into an enum list element that returns a left-shifted '1' and used this digit to set a flag in a 32 or 64 bit integer on receipt of the first call and when the flag is reset on the second, I execute the CPU-intensive operation(s).

但是,它让我觉得这是一个非常小的开销实现每个案例。有没有人有任何其他'首选'的方式区分'willChange'和'didChange的回调,而不允许相同的处理两次?

However, it strikes me that this is a non-trivial overhead to implement for every case. Does anyone have any other 'preferred' way of differentiating between the callback for 'willChange' and that for 'didChange' without allowing the same processing to be done twice?

我已经搜索了苹果自己的文档和这个帮助组大量的替代品,但苹果自己的文档实际上没有详细了解这个问题,这个组中的几个人也与类似的关注搏斗。在两个实例中都没有提供确定的解决方案。如果有人知道更好的方式 - 除了躲避willChange使用交替的旗帜 - 我会非常感谢。 (为什么苹果只能在更改字典中添加一个'phase'键)

I have scoured Apple's own documentation and this help group copiously for alteranatives but Apple's own doc doesn't actually go in to much detail on the subject and several people in this group have also wrestled with a similiar concern. In neither instance has a definitive solution been offered. If anyone knows of a better way - other than dodging the 'willChange' using alternating flags - I'd be very grateful. (Why couldn't Apple just include a 'phase' key in the change dictionary???)

推荐答案

如果您想要判断回调是之前还是之后,您可以在更改字典中查找NSKeyValueChangeNotificationIsPriorKey键。如果是事先通知,这个键将等于 [NSNumber numberWithBool:YES] (附带地,字典也不会包含NSKeyValueChangeNewKey的值)存在/值NSKeyValueChangeNotificationIsPriorKey是权威的,所以如果你看到它,当你不期望,你可能会得到双回调。

If you want to tell whether a callback is "before" or "after" you can look for the NSKeyValueChangeNotificationIsPriorKey key in the change dictionary. If it's a prior notification, this key will be equal to [NSNumber numberWithBool: YES] (incidentally the dictionary will also not contain a value for the NSKeyValueChangeNewKey) The presence/value of NSKeyValueChangeNotificationIsPriorKey is authoritative, so if you're seeing it when you're not expecting to, you might be getting double callbacks.

如果你得到双回调它可能是,因为它听起来像是在VectorVictors的情况下,运行时正在触发它们,你正在释放它们。如果你计划调用will / didChangeValueForKey:手动管理你的KVO通知,(你不想要双重通知,你应该实现以下类方法:

If you're getting double callbacks it may be, as it sounds like it was in VectorVictors case, that the runtime is firing them AND you're firing them. If you plan to call will/didChangeValueForKey: to manage your KVO notifications manually, (and you don't want double notifications,) you should implement the following class method:

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

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

这在Apple的键值观察编程指南。

这篇关于KVO区分willChangeValueForKey和didChangeValueForKey - 都是必要的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆