2
votes

My app periodically request updates for the objects I persist with Core Data to a web service. I then need to update the objects I have in my main context (the one provided in AppDelegate by default). It is not the user who edits the objects, so I need to avoid blocking the UI, and furthermore I'm not just modifying objects information, but deleting and adding new objects if needed.

It seems that there are two options to perform updates of NSManagedObject objects: creating a "sibling" context in a private queue, and creating a child context. Reading several posts, there are more people saying that it is better to use parent/child contexts (correct me if I'm wrong), but I don't completely understand how that works. I have some questions regarding parent/child contexts:

  1. Can a child context be in a private queue and the parent context in the main queue?
  2. I've read somewhere something about setting a merge policy, but I didn't find examples of its use, maybe is not necessary to set a merge policy when usen parent/child contexts? When would they be set? Where can I find an example or tutorial?
  3. If I set my private context as child of the main context, and I save the child private context, will the objects in private context "replace" the objects in the main context as I want? (including deleting the objects that are no longer present in the private context and the new ones)... I mean... does the whole child context replace the whole parent context?
  4. Would it be better to save the private context without being a child of the main one, and then clearing and refetching all the new data in the main context?

I really need help with this issue, thanks in advance.

1

1 Answers

0
votes
  1. Yes the child can be in a private queue and the parent in main, and the opposite way is valid too.

  2. Merge policy...

You use a merge policy object to resolve conflicts between the persistent store and in-memory versions of managed objects.

So you would most often use this when you have multiple contexts coming directly from the persistentStoreCoordinator, perhaps one Private Queue type and one Main Queue type.

The merge policy affects the result of calling

- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification

So if your deleting actions were done in the Private Queue and then saved, you could reflect that change in your UI by calling mergeChanges... on your Main context with the notification object from the NSManagedObjectContextDidSaveNotification that the save on the Private context would create.

  1. The parent context isn't replaced. Simply, the changes made in the child are overlaid onto the parent. So in your case deleting an object in the child would cause that object to delete once you saved the child.

  2. No. You'd be best to do what was described in 2 if you didn't want to use parent - child contexts. What you describe is discarding your current Main context and creating a new one to reflect the new state of the PSC. Its not awful but it is expensive and if your UI has any tight binding to managed objects you need to make sure those objects are reset also. Its cheaper just merge the save.

Using mergeChangesFromContextDidSaveNotification: has been measured to be quicker than parent->child for change propagation but possibly you may find parent->child to be clearer in a readability sense.