I have a navigation based application using Core Data and several levels of drill-down navigation. At the last level of the navigation I add records to the managed object store.At each level of navigation I create an array of view controllers for the next UITableView.
My question concerns the placement of the Core Data stack methods which create the managedObjectContext, managedObjectModel and the persistentStoreCoordinator.
Do I create these methods in the highest level view controller that needs to fetch data from the persistentStore and then pass a context object to the lower level viewcontrollers? Do I also need to pass a coordinator?
Many questions seem to point to putting these methods in the App Delegate but then many answers say “Do Not” put them in the app delegate. So where is the best place for these methods and which objects need to be passed to allow all necessary levels to fetch from the data store?
First, some pre-requisites:
If you’re building an application that uses Core Data, then you will most probably encounter situations where you will need to have more than one managed object context (MOC) around. You will however need one MOC that will "live" throughout the whole application session. Call that your main MOC (since you’ll be accessing it from the main thread only!!).
More rarely and depending on your application, you may also encounter situations where you will need more than one NSPersistentStoreCoordinator. In my answer I will stick to the case where a single coordinator is required. As for your NSManagedObjectModel, that is entirely dependent on your application. Usually, you only need one of those.
To answer your questions:
I suggest having your main MOC be owned by the AppDelegate, since the latter is a singleton that lives for as long as the application lives. You can put the methods for creating/saving the main MOC in the AppDelegate, or delegate these tasks to a utility class. I find the second option a little cleaner, as you can use that utility class to add methods that create other MOCs on the fly, or to get a reference to the main MOC, from any controller in your application. That way, you avoid calling the AppDelegate all the time.
Note also, that if you already have a
NSManagedObjectin your hands, you can get the reference to the MOC that it’s registered with, simply by calling[yourManagedObject managedObjectContext]. Once you have the MOC reference, you can get the associatedNSPersistentStoreCoordinatorandNSManagedObjectModelreferences. (This is to answer your question about "passing the coordinator": I prefer working withNSManagedObjects and theNSManagedObjectContextsince they are at the top-most level of the abstraction, instead of passing around the coordinator or the model).Hope this helps!