Question

In every method in every class of my iOS app, with the exception of AppDelegate, I have the following line of code:

NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];

In my AppDelegate.h file I have this:

NSManagedObjectContext *localContext;

and in my AppDelegate.m file I have this:

    localContext = [NSManagedObjectContext MR_contextForCurrentThread];

I recently read in SO that I should have ONE such line of code in AppDelegate, and then have multiple references to it from all of the other classes/methods.

If I leave this line of code out of all of the classes with the exception of AppDelegate, will I be accomplishing that, but is this the best way to it?

UPDATE This is the code I added to my AppDelegate.h file:

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) NSManagedObjectContext *localContext;

This is the code I added to my AppDelegate.m file:

//  set default MagicalRecord context in all View Controllers
UITabBarController *tbc = (UITabBarController *)self.window.rootViewController;

UINavigationController *nc = tbc.viewControllers[0];
CalendarViewController *cvController = (CalendarViewController *)nc.topViewController;
cvController.localContext = self.managedObjectContext;

nc = tbc.viewControllers[1];
WeeksApptsViewController *waController = (WeeksApptsViewController *)nc.topViewController;
waController.localContext = self.managedObjectContext;

nc = tbc.viewControllers[2];
CustomerSetupController *csController = (CustomerSetupController *)nc.topViewController;
csController.localContext = self.managedObjectContext;

nc = tbc.viewControllers[3];
AppointmentsViewController *avController = (AppointmentsViewController *)nc.topViewController;
avController.localContext = self.managedObjectContext;

nc = tbc.viewControllers[5];
SettingsViewController *sController = (SettingsViewController *)nc.topViewController;
sController.localContext = self.managedObjectContext;

When I run the app in the debugger, it crashes on this line of code:

    CalendarViewController *cvController = (CalendarViewController *)nc.topViewController;

with the following message:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CalendarViewController viewControllers]: unrecognized selector sent to instance 0xb67ed40'

Was it helpful?

Solution

If your entire app uses only one managed object context, and you are sure that this will never change in the future, then you could actually use

NSManagedObjectContext *localContext = [NSManagedObjectContext MR_defaultContext];

in all view controllers.

But with the introduction of nested managed object contexts, Apple recommends in the Core Data Release Notes for OS X v10.7 and iOS 5.0:

Nested contexts make it more important than ever that you adopt the “pass the baton” approach of accessing a context (by passing a context from one view controller to the next) rather than retrieving it directly from the application delegate.

In the simplest case, you get a pointer to the default context in the AppDelegate:

defaultContext = [NSManagedObjectContext MR_defaultContext];

and pass this context from the AppDelegate to the first view controller, and from there to the next view controllers (e.g. in prepareForSegue when using Storyboards), and so on.

That makes the transition easier if you decide later to change the structure, e.g. to a multi-context as described here: http://www.cocoanetics.com/2012/07/multi-context-coredata/

Note also that according to this answer https://stackoverflow.com/a/20536335/1187415, MR_contextForCurrentThread is deprecated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top