Core Data NSManagedObject association count cache?
I am working on setting up a count cache for an (Foo)NSManagedObject's association(Bar). In object Foo, I want to keep a count of how many Bars it has. I want to avoid hitting the database every time I need to know how many Bars Foo has(I'm hitting it a lot). My approach was to update the Foo count using the "willSave" call back.
-(void)willSave{
if (self.isDeleted) {
s开发者_运维知识库elf.totalAssignments = [NSNumber numberWithFloat:([self.totalAssignments intValue] - 1)];
} else {
self.totalAssignments = [NSNumber numberWithFloat:([self.totalAssignments intValue] + 1)];
}
}
But, the Context complains that it's dirty. My question is, within a NSManagedObject is there a callback I can use to update another NSManagedObject's attributes before save?
The best way to handle this would be in the Foo class' accessor methods for the Bar
relationship.
If the relationship is Foo.bars
, the Foo
class will have accessors that look like:
addBarsObject:
removeBarsObect:
addBarsObjects:
removeBarsObjects:
... that will look like:
- (void)addBarsObject:(NSManagedObject *)value {
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"bars" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"bars"] addObject:value];
[self didChangeValueForKey:@"bars" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
... and you just need to modify it like so:
- (void)addBarsObject:(NSManagedObject *)value {
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"bars" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"bars"] addObject:value];
[self didChangeValueForKey:@"bars" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
self.barCount = [NSNumber numberWithFloat:([self.barCount intValue] + 1)];
//... or
self.barCount=[self.bars count];
}
Change all the Foo.bars
accessor methods to track the change in the relationship as you go. This has the added advantage of keeping track of the count between saves which you probably actually need.
I think you can do this before you call NSManagedObjectContext
's (BOOL)save:(NSError **)error
. You can create a method where all calls related to the NSManagedObject
's assignment converge & totalAssigments
is updated before calling save
.
HTH,
Akshay
精彩评论