web-dev-qa-db-ja.com

Core-Data iPhone:NSManagedObjectModelが見つかりませんでした

コアデータの学習補助として、AppleのCoreDataBooksサンプルプロジェクトを使用しています。

アプリを読み込んだときに、Booksテーブルビュー(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では、RootViewControllerではなくMenuViewControllerを呼び出すようにMainWindow.xibを変更しました。

したがって、アプリが読み込まれ、メニューがボタンで正しく表示されます。ボタンをクリックすると、アプリケーションがRootViewControllerのviewDidLoad内でクラッシュします。

ここでクラッシュします:

- (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''

この例外について読みましたが、解決するための適切な手順がわかりません。

35
CraigH

OK。

RootViewControllerのviewDidLoad内に次のコードを配置すると、エラーが発生しなくなります。

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

私はここで同様の問題を抱えている誰かを見つけました: link text

Aryehがその投稿で指摘したように、「要するに、まだ設定されていないobjectContextからエンティティをフェッチしようとしています。したがって、このビューをロードする前に、すぐに設定するか、アプリの他の場所で設定するかを選択できます。 」

87
CraigH

ApplicationDidFinishLaunchingでは、次のことを行っています。

rootViewController.managedObjectContext = self.managedObjectContext;

しかし、self.managedObjectContextが設定されているコードが表示されません。 applicationDidFinishLaunchingはかなり早い段階で呼び出されます。管理オブジェクトコンテキストを設定してよろしいですか?

4
Doug Richardson

コアデータモデルをまったく変更しましたか?このエラーは、基になるSQLiteデータベースを変更せずにアプリのコアデータモデルを変更した場合によく発生するため、保存されているデータとモデルが同期していません。

シミュレータまたはテストデバイスからアプリを完全に削除してから、再インストールして再試行してください。

3
Tim

開発中、後で追加したエンティティを見つけることができませんでした。私のために働いたもの:(基本的には正気のヒント:-)

データモデルを変更するたびにアプリをアンインストールしてください!

データモデルは、インストールの間にコアデータによってキャッシュされ、整合性が損なわれないようにします。変更をテストできるように、シミュレーター/ iPhoneからアプリを削除します。

PS:誰もがそれを自動的に行う方法を知っていますか?

0
Luc Bloom