Search code examples
iosconcurrencynsmanagedobjectcontext

NSManagedObjectContext - How to associate childcontext data with parentcontext data?


I'm confused on how the a child MOC (NSPrivateQueueConcurrencyType) works with a parent MOC (NSMainQueueConcurrencyType) with respect to the following scenario. I need to has a background thread check a web server for new or updated data. When something is received, I need to save or update the parent MOC. Sounds simple enough, and I see various examples. However, I'm still confused on a couple of things.

When processing data in the background thread, I can easily save the object in the child MOC. However, in my data model, I have relationships set up as recommended. So, for example, a ConversationThread will contain an array of Messages. Each Message will have Message.parentConvoThread set in the relationship. So, whenever I'm getting new messages from the server...

  1. How do I associate the new Message object, which is created in the child privateMOC, with the ConversationThread (currently in the parent mainMOC)?

Now, say that I'm getting updated personal info for the person who wrote the message. I see they have updated data on the server, so I need to update their data in app. In the privateMOC...

  1. How do I get the actual object (say it's MyContact) from the mainMOC to explicitly update? or...
  2. If I create a new MyContact in the privateMOC, how do I merge that with the currently existing MyContact in the mainMOC? ...or does it automagically happen somehow? (<- I've read a lot of older threads that say you to use NSManagedObjectDidChangeNotification and manually merge but that this isn't necessary anymore...but how/why?)

Finally, a couple of questions about searching...

  1. Can a search against the child privateMOC return results from the parent mainMOC (say if an entity exists in the parent but not the child)?
  2. If the answer to #1 is true, what happens if the entity exists in both but hasn't been merged?

I'm quite confused on how they work together. Any help is greatly appreciated.


Solution

  • NSManagedObjectContexts are in memory caches of the data from an NSPersistentStore. A fetch on a child context will be executed through the parent context on the NSPersistentStore, and the data from the objects will be retrieved from either the cache in the child context, the parent context, or all the way from the persistent store (wherever it can first find the data).

    If you are fetching from a child context, the results will be retrieved through the parent context, and you can expect this fetch request to return objects as though you fetched from the parent context.

    Going the other direction, as long as all the changes you have made to your child context have been saved, those changes will be reflected in the parent context, because core data automatically handles the merge from child to parent.

    The only trick is if you have references to objects in the child context, and changes are saved in the background to the parent context, you will either need to re-fetch those objects on the child context to get changes from the parent, or you can manually merge the changes on the parent's NSManagedObjectContextDidSaveNotification. See this post for more information: How to keep a child NSManagedObjectContext up to date when using bindings.