Key-Value Observing an NSMutableSet

泪湿孤枕 提交于 2019-11-30 04:03:32

问题


In a plain class I have a NSMutableSet property. Whenever objects are added to or removed from the set, I want to perform some custom code. I know I could write a few addObjectToSet:-like methods to the class, but I was wondering if there's a more elegant solution with direct KVO on the set.

As it turns out, NSSet will raise an exception when you try to add an observer to it. Not surprisingly, for there's probably no named keyPath to observe. The documentation is pretty clear about the exception, but I don't understand the suggested workaround:

Instead of observing a set, observe the unordered to-many relationship for which the set is the collection of related objects.

Could someone reiterate what this means? And what a workaround would then look like?


回答1:


That's a pretty dense way of saying "don't add an observer to the set itself, add an observer to the class that contains the set":

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

The one tricky bit is that you need to wrap all your accesses to the set in order for the proper notifications to be sent. In the class containing the set:

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

There are also two notification methods specifically for sets: willChangeValueForKey:withSetMutation:usingObjects: and didChangeValueForKey:withSetMutation:usingObjects:; you may find that they work better for you than the generic "value change" methods.

All that said, I believe that the solution you mentioned in your first paragraph, and outlined by Peter Hosey in the question Girish linked to, is probably the best way to go.




回答2:


From Apple's documentation on NSSet (and, by inference and implication, NSMutableSet):

NSSet objects are not observable, so this method raises an exception when invoked on an NSSet object. Instead of observing a set, observe the unordered to-many relationship for which the set is the collection of related objects.

I'm glad you seem to have found an answer, but the fact that your initial approach was flawed (in that you assumed you could use addObserver on an NSSet), this needed to be mentioned, regardless.




回答3:


It's actually pretty clear when you relate it to an example:

If you have a class Bank that has a NSSet of Accounts, don't add the observer on Bank.accounts, add the observer on Account.bank



来源:https://stackoverflow.com/questions/6403570/key-value-observing-an-nsmutableset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!