Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autoupdating NSManagedObject property modification timestamp

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?

like image 254
iHunter Avatar asked Dec 28 '11 22:12

iHunter


2 Answers

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).

like image 193
jrturton Avatar answered Oct 16 '22 14:10

jrturton


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.

like image 40
Ash Furrow Avatar answered Oct 16 '22 14:10

Ash Furrow