7

在一个普通的类中,我有一个 NSMutableSet 属性。每当将对象添加到集合中或从集合中删除时,我都想执行一些自定义代码。我知道我可以为类编写一些类似addObjectToSet:的方法,但我想知道是否有更优雅的解决方案,直接使用 KVO。

事实证明,当您尝试向其添加观察者时,NSSet 将引发异常。毫不奇怪,因为可能没有要观察的命名 keyPath。文档对异常非常清楚,但我不明白建议的解决方法:

与其观察集合,不如观察无序的多对多关系,其中集合是相关对象的集合。

有人可以重申这意味着什么吗?那么解决方法会是什么样子?

4

3 回答 3

6

这是一种非常密集的说法:“不要将观察者添加到集合本身,将观察者添加到包含该集合的类”:

[myObjWithASetAsIvar addObserver:self
                      forKeyPath:@"nameOfIvarHoldingTheSet"
                         options:NSKeyValueObservingOptionNew
                         context:nil];

一个棘手的问题是您需要包装对集合的所有访问,以便发送正确的通知。在包含集合的类中:

[self willChangeValueForKey:@"nameOfIvarHoldingTheSet"];
// Do something with the set
[self didChangeValueForKey:@"nameOfIvarHoldingTheSet"];

还有两种专门针对集合的通知方法:willChangeValueForKey:withSetMutation:usingObjects:didChangeValueForKey:withSetMutation:usingObjects:; 您可能会发现它们比通用的“值更改”方法更适合您。

综上所述,我相信您在第一段中提到的解决方案,以及Peter Hosey在 Girish 所链接的问题中概述的解决方案,可能是最好的方法。

于 2011-06-19T18:18:39.687 回答
1

来自 Apple 关于 NSSet 的文档(以及,通过推断和暗示,NSMutableSet):

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

我很高兴您似乎找到了答案,但是您的初始方法存在缺陷(因为您假设您可以在 NSSet 上使用 addObserver)这一事实,无论如何都需要提及。

于 2016-03-15T02:22:26.283 回答
0

当您将其与示例相关联时,实际上非常清楚:

如果您有一个具有 NSSet 帐户的银行类,请不要在 Bank.accounts 上添加观察者,在 Account.bank 上添加观察者

于 2018-01-24T12:07:56.860 回答