Reputation: 120334
Consider an Core Data entity with two properties: text
and -for the sake of simplicity- textLength
. textLength
is a property that is calculated every time text
changes. I have three requirements:
textLength
every time text
changes, ideally inside the NSManagedObject
subclass.textLength
cannot be calculated on demand for performance reasons (the actual calculated property that I'm using is much more expensive to calculate).text
changes.My solution is almost there. I'm providing a custom accessor for setText:
, like this:
- (void)setText:(NSString *)text
{
static NSString *key;
if (!key) key = NSStringFromSelector(@selector(text));
[self willChangeValueForKey:key];
[self setPrimitiveText:text];
self.textCount = text.count;
[self didChangeValueForKey:key];
}
And using KVO in the UI to observer text changes:
[someObject addObserver:self forKeyPath:NSStringFromSelector(@selector(text)) options:NSKeyValueObservingOptionNew context:someContext];
This works fine in most cases, except when I perform undo. I take that Core Data calls setPrimiteValue:forKey:
directly, and this does not trigger my calculation logic. As a consequence, when the UI is notified of the change, the textLength
value is outdated.
Short of calculating textLength
on demand, where should the calculation logic be?
Upvotes: 1
Views: 271
Reputation: 119031
This is the purpose of the - (void)awakeFromSnapshotEvents:(NSSnapshotEventType)flags
method. It tells you the reason for the snap shot change and allows you to update computed / derived data.
(when you update the derived value you should set it using the appropriate primitive method)
Upvotes: 1