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.
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]
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);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With