Наблюдение за зависимыми ключами во взаимосвязи «ко многим»

#objective-c #cocoa #core-data #cocoa-bindings #key-value-observing

#objective-c #cocoa #ядро-данные #привязки cocoa #наблюдение за ключом-значением

Вопрос:

У меня есть объект основных данных «bid», который имеет отношение ко многим «элементам», называемым «itemLink».

в IB у меня есть текстовое поле, привязанное к «итогу», и это почти работает.

В «bid.m» у меня есть:

 - (NSDecimalNumber *)total
{
    return [self valueForKeyPath:@"itemLink.@sum.price"];
}
  

У меня также есть:

   (NSSet *)keyPathsForValuesAffectingTotal { 
    return [NSSet setWithObjects:@"itemLink", nil]; 

}
  

При добавлении или удалении элемента «total» обновляется, как и ожидалось. Но если вы измените «элемент» в наборе itemLink, общее количество не обновляется. Как заставить KVO видеть, когда изменился связанный объект в связанном NSSet?

Спасибо

Ответ №1:

Похоже, ваша проблема связана с тем фактом, что keyPathsForValuesAffectingTotal упоминается только ключевой путь «itemLink».

Поскольку это путь отношения «ко многим», вы фактически указываете своему объекту bid наблюдать за набором изменений. Все, что делает набор, — это управляет тем, являются ли объекты его членами или нет. Итак, это объясняет, почему вы получаете обновления при добавлении или удалении элементов из «itemLink», но и только.

Вас интересует не только то, какие элементы являются членами набора, но и (изменяемые) свойства этих элементов — цена в данном случае. Итак, в дополнение к вышесказанному, вы хотите, чтобы каждый элемент «itemLink» уведомлял всех наблюдателей о «общем» ключе соответствующего объекта bid о том, что «цена» менялась всякий раз, когда она менялась.

К сожалению, это не так просто, как добавить «itemLink.price» в качестве зависимого ключевого пути в ваш класс ставок, поскольку KVO не позволяет вам наблюдать отношения «через» ко многим.

Если вы используете подкласс NSManagedObject для экземпляров вашей сущности Item, вы могли бы добавить эту функциональность вручную. Переопределите automaticallyNotifiesObserversForKey: в своем классе Item, чтобы сообщить Cocoa, что вы собираетесь вручную управлять уведомлениями KVO для ключа «цена», затем реализуйте свой собственный setPrice: метод, который отправляет соответствующее уведомление. Что-то вроде этого:

 - (void)setPrice:(id)inPrice
{
    // bid = inverse relationship of itemLink
    [[self valueForKey:@"bid"] willChangeValueForKey:@"total"];
    [self willChangeValueForKey:@"price"];

    [self setPrimitiveValue:inPrice forKey:@"price"];

    [self didChangeValueForKey:@"price"];
    [[self valueForKey:@"bid"] didChangeValueForKey:@"total"];
}
  

Ответ №2:

Я написал некоторый код для поддержки зависимых ключей во взаимосвязи «ко многим».

https://github.com/macoun/DerivedDependency

Он также поддерживает кэширование вычисляемых значений.