【问题标题】:KVO on an NSCountedSet?NSCountedSet 上的 KVO?
【发布时间】:2009-10-22 22:44:13
【问题描述】:

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

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

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

编辑 - 这是观察者(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。

【问题讨论】:

  • 你是如何改变设置的?你在使用符合 KVO 的访问器吗?
  • countedSet 声明为属性(非原子,保留)并正确合成。我正在使用 [myCountedSet addObject:newObject] (及其反向 removeObject:) 来修改集合。也许我需要一个 countOfCountedSet 方法?

标签: cocoa cocoa-touch key-value-observing


【解决方案1】:

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

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

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

更多细节 in the Model Object Implementation Guide 和 in the Core Data Programming Guide(尽管这不是 Core Data 特有的)。

【讨论】:

  • 请注意,数组也是如此。如果你从 KVO 下改变一个可变数组,它不会发送通知。
【解决方案2】:

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

您不想将options 设置为非零值吗?比如NSKeyValueObservingOptionNew

Mike Ash 的 KVO Helper 也非常出色。

来自 addObserver 上的 NSSet 文档:

NSSet 对象是不可观察的,所以 此方法在以下情况下引发异常 在 NSSet 对象上调用。代替 观察集合,观察无序 对多关系的集合 是相关对象的集合。

【讨论】:

  • 我什至不知道你添加的最后一点“......而不是观察一个集合,而是观察无序的多对多关系,该集合是相关对象的集合”是什么意思? !?所以集合不能被观察?
  • 但我并不想观察“NSSet 对象”。我只想观察集合本身……或者更具体地说,观察集合的“计数”。如果它包含的对象数量增加或减少,我希望我的观察者得到通知......如果可能的话。
  • 看看 mutableSetForValue: mutableArrayValueForKey: 和 mutableSetValueForKey: 返回的集合代理对象也支持自动通知。这适用于支持索引访问器方法 insertObject:inAtIndex:、replaceObjectInAtIndex: 和 removeObjectFromAtIndex: 的一对多关系。 bit.ly/r0A20
  • 索引访问器仅适用于数组。但是,也有用于集合的访问器模式(add<Key>Object: 等)。
【解决方案3】:

需要检查的一些事项:

  1. myController 不是nil?如果是nil,addObserver:::: 消息就会无声无息地落在地板上。
  2. 您的方法是否被调用?也许它被调用了,但不是你期望的关键路径。 (我也不希望这样,但值得一试。)

【讨论】:

  • 我验证了 myController 不是零。甚至移动了一些东西,但无济于事......不,observeValueForKeyPath 方法根本没有被调用。所以接线一定很麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多