How to get managedObjectContext for viewController other than getting it from appDelegate? How to get managedObjectContext for viewController other than getting it from appDelegate? ios ios

How to get managedObjectContext for viewController other than getting it from appDelegate?


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.


The singleton approach has worked best for me when it comes to grabbing my Managed Object Context. It really depends on the complexity of your app, but in my case I typically keep one Managed Object Context and work with temporary nested contexts when I need to make changes.

By using a singleton-based "DataManager" class that contains all the Core Data initialization methods with public references to the the Managed Object Model and Context I am able to get to the data by importing my "DataManager.h" class and making calls to the singleton:

// I have a method to create an object that requires the Manage Object Context, so I call it from the DataManager singletonSomeObject *newObject = [SomeObject createObjectInContext:[[DataManager sharedInstance] managedObjectContext]];// I have a method in DataManager to save the context[[DataManager sharedInstance] saveContext];

That is actually the simplified version. I typically use nested Managed Object Contexts so that my main Managed Object Context is not modified until that addition or modification of a Managed Object is confirmed by the user. That complexity can all be contained in the "DataManager" class.

This is slightly off-topic, but in case you need to learn more about nested contexts: I had serious issues when NOT using nested contexts to make changes to the main Managed Object Context. This article, while some of it went over my head, helped me understand and implement nested contexts:

http://www.cocoanetics.com/2012/07/multi-context-coredata/