4

我想监视一个 NSCountedSet 以查看其内容是否发生变化。设置 KVO 似乎可以编译,但没有被触发。第一个问题:你能观察一组吗?如果是这样,那么此消息是否有问题?

    [subViewA addObserver:subViewB forKeyPath:@"countedSet" options:0 context:NULL];

如果有帮助,我真的只是想监控集合中的(对象数量)的计数

编辑 - 这是观察者(subViewB):

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context {
    if ([keyPath isEqual:@"countedSet"]) {
        NSLog(@"Set has changed");
    }
}

Edit2 - 将 addObserver 消息从 subView 移动到 viewController。所以我试图让一个 subView 观察另一个 viewController 的 subViews 中的 NSCountedSet。关键路径是“相对于接收者”——我假设它是 subViewA。

4

3 回答 3

7

直接与 set 对象对话不会发出 KVO 更改通知。您需要以符合 KVC 的方式更改属性的设置值。有两种方法:

  1. 给业主mutableSetValueForKey:发消息。这将为您提供一个伪造的 set 对象,该对象包装该属性并围绕您对其所做的每次更改发布 KVO 通知。
  2. 为属性实现 set 访问器方法,并在任何地方使用它们。每个方法的实现都直接与底层的 set 对象对话;所有不在这些方法之一中的代码都应该通过它们。因此,例如,要添加一个对象,您不应该使用[myCountedSet addObject:foo](except in addCountedSetObject:); 你应该[self addCountedSetObject:foo]改用。

我推荐#2。这听起来像是更多的工作,但它并不多,而且它产生了非常好的代码。

模型对象实现指南核心数据编程指南中的更多细节(即使这不是特定于核心数据)。

于 2009-10-23T01:14:39.980 回答
3

对于无序对多关系,肯定有 KVO 手动更改方法。

您不想将选项设置为非零吗?例如,NSKeyValueObservingOptionNew

Mike Ash 的KVO Helper也非常出色。

来自 addObserver 上的 NSSet 文档:

NSSet 对象是不可观察的,因此当在 NSSet 对象上调用此方法时会引发异常。与其观察集合,不如观察无序的多对多关系,其中集合是相关对象的集合。

于 2009-10-22T22:48:28.803 回答
0

需要检查的一些事项:

  1. myController是非nil?_ 如果是nil,则addObserver::::消息只会无声无息地落在地板上。
  2. 您的方法是否被调用?也许它被调用了,但不是你期望的关键路径。(我也不希望这样,但值得检查。)
于 2009-10-22T23:00:43.760 回答