I am using Apple's CoreDataBooks sample project as a learning aid for core data.
我正在使用Apple的CoreDataBooks示例项目作为核心数据的学习辅助工具。
I modified the app so that when the app loads I show a menu page first - not the Books tableview (RootViewController).
我修改了应用程序,以便在应用程序加载时首先显示菜单页面 - 而不是Books tableview(RootViewController)。
I have done the following:
我做了以下事情:
I created a menu page in interface builder (just a view with a button on it)
我在界面构建器中创建了一个菜单页面(只是一个带有按钮的视图)
The CoreDataBooksAppDelegate.h now looks like this:
CoreDataBooksAppDelegate.h现在看起来像这样:
// for the menu
@class MenuViewController;
@interface CoreDataBooksAppDelegate : NSObject <UIApplicationDelegate> {
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
UIWindow *window;
UINavigationController *navigationController;
//for the menu
MenuViewController *viewController;
}
- (IBAction)saveAction:sender;
//for the menu
@property (nonatomic, retain) IBOutlet MenuViewController *viewController;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, readonly) NSString *applicationDocumentsDirectory;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@end
The CoreDataBooksAppDelegate.m looks like this:
CoreDataBooksAppDelegate.m如下所示:
#import "CoreDataBooksAppDelegate.h"
#import "RootViewController.h"
// for the menu
#import "MenuViewController.h"
@implementation CoreDataBooksAppDelegate
@synthesize window;
@synthesize navigationController;
// for the menu
@synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
- (void)applicationDidFinishLaunching:(UIApplication *)application {
RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
rootViewController.managedObjectContext = self.managedObjectContext;
// for the menu
[window addSubview:viewController.view];
// Configure and show the window
[window makeKeyAndVisible];
}
The rest of CoreDataAppDelegete.m remains unchanged.
CoreDataAppDelegete.m的其余部分保持不变。
In the MenuViewController when the button is clicked, the following action takes place:
单击按钮时,在MenuViewController中,将执行以下操作:
RootViewController *modalViewController1 = [[[RootViewController alloc] initWithNibName:nil bundle:nil] autorelease];
[self presentModalViewController:modalViewController1 animated:YES];
In IB I changed the MainWindow.xib to call the MenuViewController rather than the RootViewController.
在IB中,我更改了MainWindow.xib以调用MenuViewController而不是RootViewController。
So, the app loads and the menu is displayed properly with the button. Upon clicking the button the application crashes inside of the RootViewController's viewDidLoad.
因此,应用程序加载并使用按钮正确显示菜单。单击按钮后,应用程序在RootViewController的viewDidLoad内部崩溃。
It crashes right here:
它崩溃了:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1 START viewDidLoad RootViewController");
self.title = @"Books";
// Set up the edit and add buttons.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
NSLog(@"2 setup button viewDidLoad RootViewController");
// Configure the add button.
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addBook)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
NSLog(@"3 viewDidLoad RootViewController");
NSError *error;
// HERE IS THE CRASH SITE
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Does not reach this point in viewDidLoad RootViewController");
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort(); // Fail
}
NSLog(@"END viewDidLoad RootViewController");
}
In the console I receive the following:
在控制台中,我收到以下内容:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Book''
I have read about this exception but I do not know the proper steps to resolve it.
我已阅读有关此异常的信息,但我不知道解决此问题的正确步骤。
4 个解决方案
#1
87
Ok.
好。
Placing the following code inside of the RootViewController's viewDidLoad eliminates the error:
将以下代码放在RootViewController的viewDidLoad中可以消除错误:
if (managedObjectContext == nil)
{
managedObjectContext = [(CoreDataBooksAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", managedObjectContext);
}
I found someone with a similar problem here on SO: link text
我在SO上发现了一个有类似问题的人:链接文字
As Aryeh pointed out in that post: "In short you are trying to fetch an entity from an objectContext that hadn't been set up yet. Your options therefore are to set it up right then or do elsewhere in the app before this view loads."
正如Aryeh在那篇文章中指出的那样:“简而言之,你正试图从尚未设置的objectContext中获取实体。因此,您的选项是在此视图加载之前将其设置为正确或在应用程序中的其他位置“。
#2
4
In applicationDidFinishLaunching: you're doing the following:
在applicationDidFinishLaunching中:您正在执行以下操作:
rootViewController.managedObjectContext = self.managedObjectContext;
But I don't see the code where self.managedObjectContext is setup. applicationDidFinishLaunching is called pretty early on. Are you sure you setup the managed object context?
但我没有看到设置self.managedObjectContext的代码。 applicationDidFinishLaunching很早就被调用了。您确定设置了托管对象上下文吗?
#3
3
Did you change the Core Data model at all? That error is common when the Core Data model for an app changes without also changing the underlying SQLite database, so the stored data and the model are out of sync.
你有没有改变核心数据模型?当应用程序的Core Data模型发生更改而不更改底层SQLite数据库时,该错误很常见,因此存储的数据和模型不同步。
Try completely removing your app from the Simulator or testing device, then reinstalling it and trying again.
尝试从模拟器或测试设备中完全删除您的应用程序,然后重新安装并再次尝试。
#4
0
During my development, I could not find Entities that I added later on. What worked for me: (Basically a sanity-tip :-)
在我的开发过程中,我找不到我后来添加的实体。什么对我有用:(基本上是一个理智小费:-)
Uninstall the App EVERY TIME you change the Data Model!
每次更改数据模型时卸载应用程序!
The Data Model is cached by Core Data between installs, to make sure the integrity stays in tact. Delete the App from the simulator / iPhone to be able to test your changes.
Core Data在安装之间缓存数据模型,以确保完整性保持完整。从模拟器/ iPhone中删除应用程序,以便能够测试您的更改。
PS: does anyone know how to do that automatically?
PS:有谁知道如何自动完成?
#1
87
Ok.
好。
Placing the following code inside of the RootViewController's viewDidLoad eliminates the error:
将以下代码放在RootViewController的viewDidLoad中可以消除错误:
if (managedObjectContext == nil)
{
managedObjectContext = [(CoreDataBooksAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", managedObjectContext);
}
I found someone with a similar problem here on SO: link text
我在SO上发现了一个有类似问题的人:链接文字
As Aryeh pointed out in that post: "In short you are trying to fetch an entity from an objectContext that hadn't been set up yet. Your options therefore are to set it up right then or do elsewhere in the app before this view loads."
正如Aryeh在那篇文章中指出的那样:“简而言之,你正试图从尚未设置的objectContext中获取实体。因此,您的选项是在此视图加载之前将其设置为正确或在应用程序中的其他位置“。
#2
4
In applicationDidFinishLaunching: you're doing the following:
在applicationDidFinishLaunching中:您正在执行以下操作:
rootViewController.managedObjectContext = self.managedObjectContext;
But I don't see the code where self.managedObjectContext is setup. applicationDidFinishLaunching is called pretty early on. Are you sure you setup the managed object context?
但我没有看到设置self.managedObjectContext的代码。 applicationDidFinishLaunching很早就被调用了。您确定设置了托管对象上下文吗?
#3
3
Did you change the Core Data model at all? That error is common when the Core Data model for an app changes without also changing the underlying SQLite database, so the stored data and the model are out of sync.
你有没有改变核心数据模型?当应用程序的Core Data模型发生更改而不更改底层SQLite数据库时,该错误很常见,因此存储的数据和模型不同步。
Try completely removing your app from the Simulator or testing device, then reinstalling it and trying again.
尝试从模拟器或测试设备中完全删除您的应用程序,然后重新安装并再次尝试。
#4
0
During my development, I could not find Entities that I added later on. What worked for me: (Basically a sanity-tip :-)
在我的开发过程中,我找不到我后来添加的实体。什么对我有用:(基本上是一个理智小费:-)
Uninstall the App EVERY TIME you change the Data Model!
每次更改数据模型时卸载应用程序!
The Data Model is cached by Core Data between installs, to make sure the integrity stays in tact. Delete the App from the simulator / iPhone to be able to test your changes.
Core Data在安装之间缓存数据模型,以确保完整性保持完整。从模拟器/ iPhone中删除应用程序,以便能够测试您的更改。
PS: does anyone know how to do that automatically?
PS:有谁知道如何自动完成?