I have a Core Data entity, "bid", which has a relationship to many "items", called "itemLink".
in IB, I have a text field bound to "total", and that almost works.
In "bid.m" I have:
- (NSDecimalNumber *)total
{
return [self valueForKeyPath:@"[email protected]"];
}
I also have:
+ (NSSet *)keyPathsForValuesAffectingTotal {
return [NSSet setWithObjects:@"itemLink", nil];
}
When adding or deleting an item, "total" updates as expected. But if you change an "item" within the set of itemLink, the total is not getting refreshed. How do you get KVO to see when a related object in the linked NSSet has changed?
Thanks
It looks your problem is to do with the fact that keyPathsForValuesAffectingTotal
only mentions the keyPath "itemLink".
Since that's the path of a to-many relationship, you're effectively telling your bid object to observe a set for changes. All that a set does is manage whether objects are members of it or not. So that explains why you get updates when items are added or removed from "itemLink", but only that.
You aren't just interested in which items are members of the set though, you're also interested in the (mutable) properties of those members -- price in this case. So in addition to the above, you want each member of "itemLink" to notify all observers of the relevant bid object's "total" key that "price" has changed whenever it changes.
Unfortunately, it's not as simple as adding "itemLink.price" as a dependent keypath in your Bid class, as KVO doesn't allow you to observe 'through' to-many relationships.
If you use a NSManagedObject subclass for instances of your Item entity, you could add this functionality manually. Override + automaticallyNotifiesObserversForKey:
in your Item class to tell Cocoa you're going to manage KVO notifications manually for the "price" key, then implement your own setPrice:
method that sends the appropriate notification. Something like this:
- (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"];
}
I wrote some code to support dependent keys across to-many relationships.
https://github.com/macoun/DerivedDependency
It also supports caching of calculated values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With