2009-10-27 28 views
35

Tôi đang sử dụng dự án mẫu CoreDataBooks của Apple như một trợ giúp học tập cho dữ liệu cốt lõi.Core-Data iPhone: không thể định vị một NSManagedObjectModel

Tôi đã sửa đổi ứng dụng để khi tải ứng dụng tôi hiển thị trang menu trước tiên - không phải bảng xem sách (RootViewController).

Tôi đã làm như sau:

Tôi tạo ra một trang trình đơn trong xây dựng giao diện (chỉ cần một cái nhìn với một nút trên nó)

Các CoreDataBooksAppDelegate.h bây giờ trông như thế này:

// 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 

Các CoreDataBooksAppDelegate.m trông như thế này:

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

Phần còn lại của CoreDataAppDelegete.m vẫn không thay đổi.

Trong MenuViewController khi nút được nhấn vào, hành động sau đây xảy ra:

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

Trong IB Tôi đã thay đổi MainWindow.xib gọi MenuViewController chứ không phải là RootViewController.

Vì vậy, ứng dụng sẽ tải và menu được hiển thị đúng cách bằng nút. Khi nhấp vào nút, ứng dụng gặp sự cố bên trong chế độ xemViewDidLoad của RootViewController.

Nó bị treo ngay tại đây:

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

Trong giao diện điều khiển tôi nhận được như sau:

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

Tôi đã đọc về ngoại lệ này, nhưng tôi không biết các bước thích hợp để giải quyết nó.

Trả lời

87

Ok.

Đặt đoạn mã sau bên trong viewDidLoad của RootViewController loại bỏ các lỗi:

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

tôi tìm thấy một người nào đó với một vấn đề tương tự ở đây trên SO: link text

Như Aryeh đã chỉ ra trong bài rằng: "Trong ngắn bạn đang cố gắng lấy một thực thể từ một objectContext chưa được thiết lập. Các tùy chọn của bạn do đó là thiết lập nó ngay sau đó hoặc làm ở nơi khác trong ứng dụng trước khi khung nhìn này tải. "

3

Bạn đã thay đổi mô hình Dữ liệu cốt lõi chưa? Lỗi đó là phổ biến khi mô hình Dữ liệu cốt lõi cho một ứng dụng thay đổi mà không thay đổi cơ sở dữ liệu SQLite cơ bản, do đó dữ liệu được lưu trữ và mô hình không đồng bộ.

Thử hoàn toàn xóa ứng dụng của bạn khỏi Trình mô phỏng hoặc thiết bị kiểm tra, sau đó cài đặt lại và thử lại.

+0

Xin chào. Tôi đã đi xa đến mức đặt lại nội dung và cài đặt trên trình mô phỏng. Trong Xcode, tôi làm trống bộ nhớ cache và làm sạch tất cả các mục tiêu. Lỗi: 'NSInternalInconsistencyException', lý do: '+ entityForName: không thể định vị NSManagedObjectModel cho tên thực thể' Sách '' vẫn xảy ra. Cảm ơn sự giúp đỡ của bạn Tim. – CraigH

+1

Bước qua chương trình trong trình gỡ lỗi - giá trị của 'managedObjectModel' khi bạn nhận được ngoại lệ là gì? 'managedObjectContext'? – Tim

+0

Xin chào. Được rồi trong trình gỡ lỗi tôi không thấy managedObjectModel - nhưng những gì tôi thấy là giá trị cho managedObjectContext là null trong khung nhìn ViewViewViewView gốc - đó là sai, nó sẽ có một giá trị ở đó. Trong phiên bản chưa sửa đổi của ứng dụng, giá trị của managedObjectContext là 0x3e2ce60 trong viewDidLoad. và trình gỡ lỗi dừng trên dòng này: NSEntityDescription * entity = [NSEntityDescription entityForName: @ "Book" inManagedObjectContext: managedObjectContext]; Đó là bên trong - (NSFetchedResultsController *) fetchedResultsController phương pháp của RootViewController. – CraigH

4

Trong applicationDidFinishLaunching: bạn đang làm như sau:

rootViewController.managedObjectContext = self.managedObjectContext; 

Nhưng tôi không thấy mã nơi self.managedObjectContext được thiết lập. applicationDidFinishLaunching được gọi khá sớm. Bạn có chắc chắn thiết lập bối cảnh đối tượng được quản lý không?

+0

Xin chào Doug. Có, bối cảnh đối tượng được quản lý được thiết lập (đây là mẫu CoreDataBooks từ Apple, tôi chỉ thêm một trình đơn để tôi để phần còn lại của mã không bị ảnh hưởng). Trong applicationDidFinishLaunching nếu tôi thay thế dòng: [window addSubview: viewController.view]; với dòng: [window addSubview: [navigationController view]]; (xem ở trên trong bài đăng câu hỏi của tôi) sau đó ứng dụng tải RootViewController ngay lập tức, chạy tốt và managedObjectContext không phải là không. Dù bằng cách nào, trong applicationDidFinishLaunching, managedObjectContext có một giá trị: . Cảm ơn. – CraigH

0

Trong quá trình phát triển của mình, tôi không thể tìm thấy Thực thể mà tôi đã thêm sau này. Điều gì đã hiệu quả đối với tôi: (Về cơ bản, một sự tỉnh táo :-)

Gỡ cài đặt M EVI M AppI THỜI GIAN bạn thay đổi Mô hình Dữ liệu!

Mô hình dữ liệu được lưu trong bộ nhớ cache bởi dữ liệu lõi giữa các lần cài đặt, để đảm bảo tính toàn vẹn vẫn giữ nguyên. Xóa ứng dụng khỏi trình mô phỏng/iPhone để có thể kiểm tra các thay đổi của bạn.

PS: có ai biết cách tự động làm điều đó không?

Các vấn đề liên quan