在普通类中,我有一个NSMutableSet属性。每当在集合中添加或删除对象时,我都想执行一些自定义代码。我知道我可以在课堂上写一些addObjectToSet:
类似的方法,但我想知道是否有一个更优雅的解决方案,直接使用KVO。
事实证明,当您尝试向其添加观察者时,NSSet将引发异常。毫不奇怪,因为可能没有可以观察到的命名keyPath。 The documentation非常清楚异常,但我不明白建议的解决方法:
不要观察集合,而是观察集合是相关对象集合的无序多对多关系。
有人可以重申这意味着什么吗?那么解决方法会是什么样的呢?
答案 0 :(得分: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:
;您可能会发现它们比通用的“价值变化”方法更适合您。
所有这一切,我相信你在第一段中提到的解决方案,以及Girish问题中的outlined by Peter Hosey,可能是最好的方法。
答案 1 :(得分:1)
来自Apple的NSSet文档(以及通过推理和暗示,NSMutableSet):
NSSet对象不可观察,因此此方法引发异常 在NSSet对象上调用时。而不是观察一组,观察 集合为集合的无序to-many关系 相关的对象。
我很高兴您似乎找到了答案,但事实上您的初始方法存在缺陷(因为您假设您可以在NSSet上使用addObserver),无论如何都需要提及。
答案 2 :(得分:0)
当你将它与一个例子联系起来时,它实际上非常清楚:
如果你有一个拥有NSSet of Accounts的班级银行,请不要在Bank.accounts上添加观察者,在Account.bank上添加观察者