有没有一种方法可以确定特定值的KVO何时开始/结束?

3
我有一些值是基于集合计算的,可能会被显示出来(因此可能有观察者),也可能不会。如果没有人观察我的计算值,我宁愿不跟踪集合中的所有成员。
我能否知道是否有任何人正在观察一个值,并且我能否知道他们何时开始观察?
对于给定的对象foo,我知道可以使用[foo observationInfo]获取在以foo为根的关键路径注册的观察者列表,但这并不会自动获取到所有指向foo的路径(实际上只获取了那些注册了观察foo的self key的路径)。
2个回答

3

从设计角度来看,这并不是一个好主意。如果您真的坚持不在没有人需要更新内容时进行更新(这可能是一个合法的情况,例如如果更新很昂贵),您可以引入启动/停止更新的方法:

- (void) beginUpdatingContents;
- (void) endUpdatingContents;

这些应该与类内的计数器绑定,如果计数器>0,则知道有人想要保持内容更新。这种解决方案是明确的,因此比使用KVO的沉默魔法更好。


2
等等,如果问题是由于静默的KVO魔法引入的,那么答案不应该是更加静默的KVO魔法吗? - Stripes
在 KVO(键值观察)的沉默魔力过于强大的某一点上,使用您的解决方案,我感觉我们可能已经接近这个点了 :) - zoul
我的第一条评论其实有85%是玩笑。另外15%是这个项目本来就是为了让我学习iOS和Core Data,所以如果我编写了“更多魔法”的版本并且决定它是“太过于神奇”,那么我离达成目标的距离比只是保守地做要近。 - Stripes
在这种情况下,你可以直接深入研究,发现KVO的限制是很好的。在Cocoa Builder上搜索KVO,有很多很棒的讨论。让我们看看这里是否有人提出了基于KVO的解决方案来解决你的问题。 - zoul
这对我来说很有效。如果是为了供其他人使用的API,我会再三考虑……但由于没有更好的答案出现,再三思考的结果可能是“无论如何都要这样做” :-) - Stripes
这是一个在Cocoa Touch中多处使用的设计模式(如果这听起来让人放心的话)。例如,可以查看UIApplicationUIDevice - zoul

2
如果你想要更多的魔法,那么重写addObserver:forKeyPath:options:context:removeObserver:forKeyPath:来追踪仍在观察你的内容如何?
我过去实际上使用的方法是创建包装对象(我称之为绑定),这些对象设置了KVO并且还向目标注册了自己。因此,用户会调用MyBinding *binding = [targetObject bindKeyPath:@"foo" ...],然后稍后调用[binding detach]。然后,绑定在幕后使用KVO并保持自己的列表,以便知道何时为空。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接