I have an NSManagedObject with two properties:
NSNumber *score;
NSDate *score_timestamp;
I want my score_timestamp field to be updated each time I update score.
I obviously cannot use -willSave method as my context is saved occasionally, and score_timestamp won't be up to date. So I should either override -setScore: or setup my managed object as a key-value observer for its own score field.
The -setScore: solution seems easy:
- (void) setScore:(NSNumber *)score
{
[self willChangeValueForKey:@"score"];
[self setPrimitiveScore:score];
[self didChangeValueForKey:@"score"];
self.score_timestamp = [NSDate date];
}
Are there any caveats in doing things that way? Or I should use a KVO solution?
Update
So far I've received two responses that my code will not work through setValue: forKey: and I'm still waiting for example. Naive calling [(NSManagedObject *)myObject setValue:value forKey:@"score"] calls my setter all the same.
So if I switch to KVO solution, should I addObserver: in all awake methods and remove it in willTurnIntoFault? Or that's not that simple?
The implementation in your question is fine. Any KVC attempt to update your value will also go through the setter method (setValue: forKey: simply searches for an accessor method matching setKey, see here for details).
You're looking for Key-Value Observing
[objectWithArray addObserver:self
forKeyPath:@"score"
options:NSKeyValueObservingOptionNew
context:nil];
Then to observe it:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
//Check if [change objectForKey:NSKeyValueChangeNewKey] is equal to "score"
//and update the score_timestamp appropriately
}
You should register for the notification when you awake from fetch and unregister when you fault, I believe.
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