KVO区分willChangeValueForKey和didChangeValueForKey – 都是必要的吗?
根据苹果自己的build议,当手动设置符合KVC / KVO的访问器时,应该包括两个 KVO方法willChange
和didChange
。 这是我在所有手动存取器方法中所做的。
但是, observeValueForKeyPath:ofObject:change:context
被调用,每个KVC方法的一半(将和做)具有完全相同的字典内容。
使用选项注册观察者时: NSKeyValueObservingOptionPrior
观察者仍然被调用两次 – 每一次调用一次 – 再一次使用相同的字典内容,只保存关键字“notificationIsPrior”包含在字典中的区别。
现在,当KVO被用来改变'CPU昂贵'的属性 – 比如改变颜色或者重新绘制一个庞大而复杂的devise,只有在'didChange'的作用下忽略(或者至less分离出)'willChange ”。 在过去,我通过将密钥string转换为返回左移“1”的枚举列表元素,并使用此数字在接收到第一个调用时以32或64位整数设置标志,以及何时该标志在第二秒重置,我执行CPU密集型操作。
然而,这让我感到这是一个不小的开销,为每个案件执行。 有没有人有任何其他“偏好”的方式来区分“willChange”和“didChange”的callback,而不允许相同的处理两次?
我search了苹果公司自己的文档,这个帮助团队大量地提供替代品,但是苹果公司自己的文档并没有涉及到这个主题的很多细节,而且这个团队中的一些人也同样遇到了类似的担忧。 在任何情况下都没有提供明确的解决scheme。 如果有人知道更好的方法 – 除了用交替的标志来避免“willChange” – 我会非常感激。 (为什么苹果公司不能在改变词典中join“阶段”键???)
我认为这是你在评论中得到的,但是为了未来的访问者的利益:
如果您想知道callback是“之前”还是“之后”,则可以在更改字典中查找NSKeyValueChangeNotificationIsPriorKey键。 如果是事先通知,这个键将等于[NSNumber numberWithBool: YES]
(顺便说一句,字典也不会包含NSKeyValueChangeNewKey的值)NSKeyValueChangeNotificationIsPriorKey的存在/值是权威的,所以如果你看到它,当你不期待,你可能会得到双重callback。
如果你得到了双重callback,就像在VectorVictors的情况下一样,运行时正在触发它们,而你正在触发它们。 如果您打算调用will / didChangeValueForKey:来手动pipe理您的KVO通知(并且您不需要双重通知),则应该实现以下类方法:
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey { BOOL automatic = NO; if ([theKey isEqualToString:@"propertyYourePlanningToManageYourself"]) { automatic = NO; } else { automatic=[super automaticallyNotifiesObserversForKey:theKey]; } return automatic; }
这在Apple的Key-Value观察编程指南中有详细描述。