Core Data and UITabBar Controller - help?

2020-06-28 22:48发布

So I have a Project with a UITabBarController and a few Navigation Controllers, and I am trying to implement Core Data. Its just not working.

I have a bit of a weird setup: UITabBarController -> Navigation Controller -> Table View Controller

I have copied all of the Core Data code and added an entity with an attribute ('Event' and 'name' - just like the tutorials). I keep getting the error: erminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Event''

The error only occurs when I switch to the Table View I want populated by the Core Data content.

I found that the error occurs on this line in the Table View Controller:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];

This seems to correspond with this (in the App Delegate):

NSManagedObjectContext *context = [self managedObjectContext];

if (!context) {

    // Handle the error.

NSLog(@"\nCould not create *context for self");

}

rootViewController.managedObjectContext = context;

Any Help?

Update: I managed to get it working (very exciting moment, and Stanford is winning at the half - so far its a good day). I am now referencing it from the App Delegate. Ahhh, this feels soo good :)

5条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-06-28 23:27

Make sure you have your TableView (rootViewController) in IB hooked up to the outlet in your app delegate.

查看更多
别忘想泡老子
3楼-- · 2020-06-28 23:33

I've ran into this same problem, i'll share my solution.

First you need a reference to the Nav Controller in the Tab Bar in the nib file, make sure you connect it up.

IBOutlet UINavigationController *navigationController;

Then, get the Controller as recommended in the support docs and send it the managedObjectContext:

SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;

Alex (from another post) is right, "You should generally stay away from getting shared objects from the app delegate. It makes it behave too much like a global variable, and that has a whole mess of problems associated with it."

查看更多
SAY GOODBYE
4楼-- · 2020-06-28 23:48

Your managed object context is probably not set and the entity "Event" is obviously not valid for a nil context.

I use a reference to my app delegate in all my view controllers so they can access the one managed object context. It sounds like others often use a singleton to manage Core Data and would get the managed object context from that.

UPDATE

There is a good discussion about where to keep the Core Data stack in Where to place the “Core Data Stack” in a Cocoa/Cocoa Touch application.

Here is some example code for keeping the Core Data stack in the app delegate:

Use Apple's standard Core Data stack implementation in YourAppDelegate. managedObjectContext is implemented as an example, but managedObjectModel and persistentStoreCoordinator must be implemented as well.

YourAppDelegate.h:

@interface YourAppDelegate : NSObject <UIApplicationDelegate> {
    // Core Data stuff
    NSManagedObjectModel *managedObjectModel;
    NSManagedObjectContext *managedObjectContext;       
    NSPersistentStoreCoordinator *persistentStoreCoordinator;

    // other app ivars
}

YourAppDelegate.m:

- (NSManagedObjectContext *) managedObjectContext {
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return managedObjectContext;
}

In every view controller, get a reference to the app delegate and use it to get the managedObjectContext as needed. For example, when setting up the fetchedResultsController;

RootViewController.h:

@interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
    NSFetchedResultsController *fetchedResultsController;

    YourAppDelegate *app;
}

RootViewController.m:

#import "RootViewController.h"
#import "YourAppDelegate.h"

@implementation RootViewController

@synthesize fetchedResultsController;

- (void)viewDidLoad {
    [super viewDidLoad];

    app = (YourAppDelegate*)[UIApplication sharedApplication].delegate;
}

- (NSFetchedResultsController *)fetchedResultsController {
    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:app.managedObjectContext];
    [fetchRequest setEntity:entity];

    // setup the batch size, predicate, & sort keys, etc

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:app.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];

    return fetchedResultsController;
}    
查看更多
够拽才男人
5楼-- · 2020-06-28 23:48

I've ran into the exact same issue and described how to fix it here:

iPhone: core data error: +entityForName: could not locate an NSManagedObjectModel for entity name 'Name'

You need to add this line to your app delegate where you create the view controllers for the tab bar:

yourViewController.managedObjectContext = self.managedObjectContext;
查看更多
三岁会撩人
6楼-- · 2020-06-28 23:49

Quoting gerry3:

It sounds like others often use a singleton to manage Core Data and would get the managed object context from that.

For anyone trying to solve this problem by implementing it using a singleton, I started new question here.

查看更多
登录 后发表回答