Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

automaticallyMergesChangesFromParent doesn't do anything

Tags:

ios

core-data

I was watching a WWDC 2016 (What's new in Core Data) video about some "new" changes and at some point it's said that this new property automaticallyMergesChangesFromParent is supposed to automatically merge the changes from the parent on the child context.

I created a simple test case:

CustomObject *customObject = [[CustomObject alloc] initWithContext:self.persistentContainer.viewContext];
customObject.name = @"TEST";
customObject.customID = 2252;
self.persistentContainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;

NSManagedObjectContext *firstContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
firstContext.parentContext = self.persistentContainer.viewContext;
firstContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
firstContext.automaticallyMergesChangesFromParent = YES;

CustomObject *contextObj = [firstContext objectWithID:customObject.objectID];
NSLog(@"NAME [%@]", contextObj.name);
customObject.name = @"JO";
[self.persistentContainer.viewContext save:NULL];
NSLog(@"NAME [%@]", contextObj.name);

The output is:

 NAME [TEST]
 NAME [TEST]

I was hoping it would be:

NAME [TEST]
NAME [JO]

if I use a [firstContext refreshAllObjects]; it will work as I expect, but it makes not difference if automaticallyMergesChangesFromParent is set to YES or NO.

Am I missing something on how this is supposed to work? The documentation doesn't help much.

Thanks.

like image 647
Wak Avatar asked Jun 07 '26 06:06

Wak


2 Answers

You are fetching and updating object in firstContext. To verify automaticallyMergesChangesFromParent, you should fetch it from self.persistentContainer.viewContext and update.

self.secondObject = [[SecondCustomObject alloc] initWithContext:self.persistentContainer.viewContext];
self.secondObject.name = @"TEST";
self.persistentContainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;



NSManagedObjectContext *firstContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
firstContext.parentContext = self.persistentContainer.viewContext;
firstContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
firstContext.automaticallyMergesChangesFromParent = YES;
//firstContext.stalenessInterval = 0;

SecondCustomObject *contextObj = [self.persistentContainer.viewContext objectWithID:self.secondObject.objectID];
NSLog(@"NAME [%@]", contextObj.name);
contextObj.name = @"JO";
[self.persistentContainer.viewContext save:NULL];
SecondCustomObject * contextObj1 = [firstContext objectWithID:self.secondObject.objectID];
NSLog(@"NAME [%@]", contextObj.name);
NSLog(@"NAME [%@]", contextObj1.name);


 NAME [TEST]
 NAME [JO]
 NAME [JO]
like image 142
Parag Bafna Avatar answered Jun 10 '26 19:06

Parag Bafna


When you set automaticallyMergesChangesFromParent = YES; and then make save in your parent context CoreData automatically calls mergeChangesFromContextDidSaveNotification: on your child context by dispatching this block on the child queue (by calling performBlock: as usual). As soon as both your contexts work on the main queue you'll see changes only on the next main loop

Try

CustomObject *contextObj = [firstContext objectWithID:customObject.objectID];
NSLog(@"NAME [%@]", contextObj.name);
customObject.name = @"JO";
[self.persistentContainer.viewContext save:NULL];
dispatch_async(dispatch_get_main_queue(), ^{
   NSLog(@"NAME [%@]", contextObj.name);
});

like image 20
karama Avatar answered Jun 10 '26 17:06

karama