Основные данные iPhone:не удалось найти NSManagedObjectModel

StackOverflow https://stackoverflow.com/questions/1632497

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

Файл 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''

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

Это было полезно?

Решение

ОК.

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

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

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

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

Другие советы

В applicationDidFinishLaunching: вы делаете следующее:

rootViewController.managedObjectContext = self.managedObjectContext;

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top