iHunter
iHunter

Reputation: 6205

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?

Upvotes: 7

Views: 1354

Answers (3)

jrturton
jrturton

Reputation: 119242

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

Upvotes: 4

Ash Furrow
Ash Furrow

Reputation: 12421

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.

Upvotes: 1

Matthew Bischoff
Matthew Bischoff

Reputation: 1043

In this method, if for any reason you modify the object not as your custom subclass, but as an NSManagedObject using setValue: forKey: the date will not be updated.

Upvotes: 0

Related Questions