Josh Kahane
Josh Kahane

Reputation: 17169

CoreData UITableViewController managedObjectContext Error

I have started playing around with CoreData and taking a new project with CoreData and building those foundations into my own project. I have reached a stage where I have more or less identically duplicated the fresh project, however I am getting an error.

This line, controller.managedObjectContext = self.managedObjectContext; is causing me problems. When I comment it out, the app simply launches with a blank UITableView, however if I include the line, it causes this error:

Universal[24718:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewController setManagedObjectContext:]: unrecognized selector sent to instance 0x1521a0'
*** First throw call stack:
(0x344558bf 0x346a51e5 0x34458acb 0x34457945 0x343b2680 0x2413 0x378367eb 0x378303bd 0x377fe921 0x377fe3bf 0x377fdd2d 0x30c30df3 0x34429553 0x344294f5 0x34428343 0x343ab4dd 0x343ab3a5 0x3782f457 0x3782c743 0x2331 0x22c8)
terminate called throwing an exception

I you need anymore code to look at, I can provide it and I hope you have an idea of whats happening. I can't see anything which would cause this, I am not getting any errors, but I get this log as that line causes the entire app to crash.

The line resides in the didFinishLaunchingWithOptions method of the app delegate, just like in a fresh core data project.

As requested, the header file for the table view controller:

#import <UIKit/UIKit.h>

#import <CoreData/CoreData.h>

@interface myTableViewController : UITableViewController <NSFetchedResultsControllerDelegate>

@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

@end

Upvotes: 4

Views: 5296

Answers (4)

mafiOSo
mafiOSo

Reputation: 183

I had the same problem. I solved it by making sure that the ManagedContextObject property is included in the root view controller (the very first view controller connected to the very first navigation controller) regardless if it uses it.

in the .h of the Root View Controller:

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

in the .m

@synthesize managedObjectContext;

apologies if my answer is dumbed down a bit. I have to dumb things down for myself in order to understand them :)

Upvotes: 1

rockstarberlin
rockstarberlin

Reputation: 1853

It depends on how your application is structured. If you use a TabBarViewController in front of all the code differs a bit

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;

    UINavigationController *navigationController = (UINavigationController *)[[tabController viewControllers] objectAtIndex:0];
    MasterViewController *controller = (MasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
    controller.managedObjectContext = self.managedObjectContext;

    return YES;
}

Upvotes: 2

occulus
occulus

Reputation: 17012

You're missing some wiring that links UIViewControllers (or subclasses thereof) up to NSFetchedResultsController. You get that for free when you set up a new project with Core Data enabled, but if you're adding Core Data to en existing project, you need to wire up a few things yourself.

For more info, please see http://wiresareobsolete.com/wordpress/2009/12/adding-core-data-existing-iphone-projects/

Upvotes: 2

Kevin Burandt
Kevin Burandt

Reputation: 1990

The reason why you are getting the error is in your AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
    return YES;
}

When using the default CoreData template the managed object context is assigned to the topViewController which no longer is MasterViewController as you've inserted a different view as your starting point. Thus the unrecognized selector sent to instance.

You have two options:

1) Remove the code that assigns the managed object context and, in the view that needs it get it like this

 [[[UIApplication sharedApplication] delegate] mainManagedObjectContext];

2) Keep the code (correct the class name), add declaration for managedObjectContext, and pass your NSManagedObjectContext object throughout all your app between all your UIViewControllers

Upvotes: 6

Related Questions