It is called dependency injection. Basically the caller/constructor should be setting the NSManagedObjectContext
onto the called/constructed.
In your AppDelegate
you should set the NSManagedObjectContext
into the rootViewController
that is associated with the UIWindow
.
Your rootViewController
should then set the NSManagedObjectContext
into the next view controller and so on.
How? It is just a simple proper on the view controller class and the caller uses:
[nextViewController setManagedObjectContext:[self managedObjectContext]];
Some others may recommend a singleton but that is another deep dark pit that is best avoided.
Update
Dependency Injection is the best approach.
It is the approach Apple has designed around. The other choice involves some form of a singleton: AppDelegate or another one.
"The downside of passing the same context between controllers is that if a same entity is modified in two different places, you have to manage the merge conflict."
That is a completely different problem and it is not going to be solved with multiple NSManagedObjectContext
instances. In fact, multiple instances will make the situation worse and guarantee a merge conflict.
In that situation, your view controllers should be listening for changes in the managed object and reacting to them. Making it impossible to update it in two places at once in the UI. The user simply cannot focus on two places at once and therefore the second location will be updated in real time.
That is the right answer for that problem.
Having both entities in the same context will make sure that works correctly. Multiple contexts will cause their to be two objects in memory with the same data and no way to notice the changes without a save to the context.
However, if you are having view controllers that are modifying data without user intervention then you have a separate problem. View controllers are for the user to modify or view data. They are not the place for any kind of background processing of the data.
If you are in an import situation then that is a different question than the one you asked. In that case you are (should be) using multiple threads (UI thread, import thread) and you must have at least one context for each.
In that situation you do risk a merge conflict and you need to code for the situation happening. First step is to change the merge policy on the NSManagedObjectContext
instances.
Update
I suspect you are misreading that documentation.
What that is describing is the ability to get the NSManagedObjectContext
out of the NSManagedObject
instance. This is absolutely useful. Take for example a view controller that has the ability to add or edit an object. By pushing just the NSManagedObject
to the view controller you can control and decide what that view controller is going to be touching. The receiving view controller knows that it needs to allow editing of the received NSManagedObject
. It does not care what NSManagedObjectContext
it is working with. It could be working with the main, it could be working with a child, it could be in isolation in a unit test, it doesn't need to know or care. It simply displays the data from the NSManagedObject
it is handed and saves the associated NSManagedObjectContext
if the user chooses to save the edits.
That documentation is NOT suggesting having some universal location for your NSManagedObjectContext
to live (aka a singleton). It is suggesting that if you have another way to access the NSManagedObjectContext
that is associated with a NSManagedObject
that it is ok to do so and definitely makes sense to do so.