Core-Data iPhone:NSManagedObjectModelが見つかりませんでした
-
06-07-2019 - |
質問
コアデータの学習支援として、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では、MainWindow.xibを変更して、RootViewControllerではなくMenuViewControllerを呼び出すようにしました。
したがって、アプリがロードされ、メニューがボタンとともに適切に表示されます。ボタンをクリックすると、アプリケーションは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''
この例外について読みましたが、それを解決するための適切な手順がわかりません。
解決
わかりました
RootViewControllerのviewDidLoad内に次のコードを配置すると、エラーがなくなります。
if (managedObjectContext == nil)
{
managedObjectContext = [(CoreDataBooksAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", managedObjectContext);
}
SOで同様の問題を抱えている人を見つけました:リンクテキスト
Aryehがその投稿で指摘したように、&quot;要するに、まだ設定されていないobjectContextからエンティティを取得しようとしています。そのため、オプションはその場で設定するか、このビューが読み込まれる前にアプリの他の場所で行うことです。&quot;
他のヒント
applicationDidFinishLaunching:次のことを実行しています:
rootViewController.managedObjectContext = self.managedObjectContext;
しかし、self.managedObjectContextがセットアップされているコードは表示されません。 applicationDidFinishLaunchingはかなり早い段階で呼び出されます。管理対象オブジェクトコンテキストをセットアップしてもよろしいですか?
コアデータモデルを変更しましたか?このエラーは、基になるSQLiteデータベースも変更せずにアプリのコアデータモデルが変更され、保存されたデータとモデルが同期していない場合によく発生します。
シミュレーターまたはテストデバイスからアプリを完全に削除してから、再インストールして再試行してください。
開発中に、後で追加したエンティティが見つかりませんでした。私のために働いたもの:(基本的に健全性のヒント:-)
データモデルを変更するたびにアプリをアンインストールしてください!
整合性が確実に維持されるように、データモデルはインストール間でコアデータによってキャッシュされます。シミュレーター/ iPhoneからアプリを削除して、変更をテストできるようにします。
PS:誰もがそれを自動的に行う方法を知っていますか?