Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data - Discard changes

Hope someone can explain what's going on.

If I get an object from my Core Data model, modify a property which is not persisted or even defined in the model! and then destroy and get the object again the value is still as previously set.

Why is this?

Promotion *promotion = [Promotion promotionWithId:[NSNumber numberWithInt:1512] inManagedObjectContext:context];
    [promotion setQuantity:[NSNumber numberWithInt:2]];
    NSLog(@"%d", [promotion.quantity intValue]);
    promotion = nil;

    promotion = [Promotion promotionWithId:[NSNumber numberWithInt:1512] inManagedObjectContext:context];
    NSLog(@"%d", [promotion.quantity intValue]);
    promotion = nil;

Output is:

2 2

For information purposes:

+(Promotion *)promotionWithId:(NSNumber *)promotionId inManagedObjectContext:(NSManagedObjectContext *) context {
    NSFetchRequest *fetchReq = [[NSFetchRequest alloc]init];
    [fetchReq setEntity:[NSEntityDescription entityForName:@"Promotion" inManagedObjectContext:context]];

    NSPredicate *query = [NSPredicate predicateWithFormat:@"promotionId=%d", [promotionId intValue]];
    [fetchReq setPredicate:query];

    NSMutableArray *resultArray = [[NSMutableArray alloc]initWithArray:[context executeFetchRequest:fetchReq error:nil]];

    if([resultArray count] > 0) {
        return [resultArray objectAtIndex:0];
    }

    return nil;
}
like image 772
Chris Avatar asked Oct 19 '11 16:10

Chris


2 Answers

Keep in mind that the changes you make to all managed objects are kept on Coredata's managed object context until you persist them (i.e. save the context).

So in your case, you are making a change to the managed object, setting it's reference to nil but not resetting the context.

This means your change is still valid and the next time you fetch the same object it will be applied.

To get rid of it completely, you will need to reset the context with:

[context reset];

From NSManagedObjectContext reset method documentation:

All the receiver's managed objects are “forgotten.” If you use this method, you should ensure that you also discard references to any managed objects fetched using the receiver, since they will be invalid afterwards.

like image 174
Rog Avatar answered Oct 28 '22 20:10

Rog


Core Data caches objects, and the cache might retain the ivars that are not defined properties.

Try [context refreshObject:promotion mergeChanges:NO] then the log statement.

like image 45
Ryan Avatar answered Oct 28 '22 20:10

Ryan