Базовые данные iPhone: не удалось найти NSManagedObjectModel - PullRequest
35 голосов
/ 27 октября 2009

Я использую пример проекта Apple CoreDataBooks в качестве учебного пособия для основных данных.

Я изменил приложение так, чтобы при загрузке приложения сначала отображалась страница меню, а не представление таблицы книг (RootViewController).

Я сделал следующее:

Я создал страницу меню в конструкторе интерфейсов (просто вид с кнопкой на нем)

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

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];
}

Остальная часть CoreDataAppDelegete.m остается без изменений.

В MenuViewController при нажатии кнопки происходит следующее действие:

RootViewController *modalViewController1 = [[[RootViewController alloc] initWithNibName:nil bundle:nil] autorelease];  
[self presentModalViewController:modalViewController1 animated:YES];

В IB я изменил MainWindow.xib для вызова MenuViewController, а не RootViewController.

Итак, приложение загружается и меню отображается правильно с помощью кнопки. При нажатии на кнопку происходит сбой приложения внутри viewDidLoad RootViewController.

Он падает прямо здесь:

- (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");
}

В консоли я получаю следующее:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Book''

Я читал об этом исключении, но не знаю, как правильно его устранить.

Ответы [ 4 ]

87 голосов
/ 29 октября 2009

Хорошо.

Размещение следующего кода внутри viewDidLoad RootViewController устраняет ошибку:

if (managedObjectContext == nil) 
{ 
    managedObjectContext = [(CoreDataBooksAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    NSLog(@"After managedObjectContext: %@",  managedObjectContext);
}

Я нашел кого-то с подобной проблемой здесь на SO: текст ссылки

Как Арье указал в этом посте: «Короче говоря, вы пытаетесь извлечь объект из objectContext, который еще не был настроен. Поэтому вы можете установить его прямо сейчас или сделать где-то еще в приложении раньше. это представление загружается. "

4 голосов
/ 28 октября 2009

В приложении DidFinishLaunching: вы делаете следующее:

rootViewController.managedObjectContext = self.managedObjectContext;

Но я не вижу кода, в котором настроен self.managedObjectContext. applicationDidFinishLaunching вызывается довольно рано. Вы уверены, что настроили контекст управляемого объекта?

3 голосов
/ 27 октября 2009

Изменили ли вы модель базовых данных вообще? Эта ошибка встречается часто, когда модель базовых данных для приложения изменяется без изменения базовой базы данных SQLite, поэтому хранимые данные и модель не синхронизированы.

Попробуйте полностью удалить приложение из симулятора или тестирующего устройства, затем переустановить его и повторить попытку.

0 голосов
/ 27 августа 2013

Во время разработки я не смог найти сущностей, которые добавил позже. Что сработало для меня: (в основном здравомыслие: -)

Удаляйте приложение КАЖДЫЙ РАЗ, когда вы меняете модель данных!

Модель данных кэшируется Core Data между установками, чтобы обеспечить целостность данных. Удалите приложение из симулятора / iPhone, чтобы иметь возможность проверить ваши изменения.

PS: кто-нибудь знает, как это сделать автоматически?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...