开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜