Наблюдение за ключом-значением NSMutableSet

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

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

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

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

3 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам