Наблюдение за ключом-значением NSMutableSet - PullRequest
7 голосов
/ 19 июня 2011

В обычном классе у меня есть свойство NSMutableSet. Всякий раз, когда объекты добавляются или удаляются из набора, я хочу выполнить некоторый пользовательский код. Я знаю, что могу написать несколько addObjectToSet: -подобных методов для класса, но мне было интересно, есть ли более элегантное решение с прямым KVO на множестве.

Как оказалось, NSSet вызовет исключение, когда вы попытаетесь добавить к нему наблюдателя. Не удивительно, потому что, вероятно, нет именованного keyPath для наблюдения. В документации достаточно ясно об исключении, но я не понимаю предложенного обходного пути:

Вместо того, чтобы наблюдать за множеством, наблюдайте неупорядоченное отношение ко многим, для которого множество является набором связанных объектов.

Может ли кто-нибудь повторить, что это значит? И как тогда будет выглядеть обходной путь?

Ответы [ 3 ]

6 голосов
/ 19 июня 2011

Это довольно плотный способ сказать "не добавляйте наблюдателя к самому набору, добавьте наблюдателя к классу, который содержит набор":

[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:; Вы можете обнаружить, что они работают лучше для вас, чем общие методы «изменения значения».

Из всего сказанного, я полагаю, что решение, которое вы упомянули в первом абзаце, и , изложенное Питером Хоси в вопросе, связанном с Гиришем, вероятно, является наилучшим путем.

1 голос
/ 15 марта 2016

Из документации Apple по NSSet (и, как подразумевается, NSMutableSet):

Объекты NSSet не наблюдаемы, поэтому этот метод вызывает исключение при вызове объекта NSSet.Вместо того, чтобы наблюдать за набором, наблюдайте неупорядоченное отношение ко многим, для которого набор является набором связанных объектов.

Я рад, что вы, кажется, нашли ответ, но тот факт, что вашпервоначальный подход был ошибочным (поскольку вы предполагали, что можете использовать addObserver в NSSet), об этом нужно было упомянуть, независимо от того.

0 голосов
/ 24 января 2018

На самом деле довольно ясно, когда вы связываете это с примером:

Если у вас есть класс Bank, который имеет NSSet Счетов, не добавляйте наблюдателя в Bank.accounts, добавьте наблюдателя в Account.bank

...