Pregunta

Estoy usando el proyecto de ejemplo CoreDataBooks de Apple como una ayuda de aprendizaje para los datos básicos.

Modifiqué la aplicación para que cuando se cargue la aplicación muestre primero una página de menú, no la vista de tabla de Libros (RootViewController).

He hecho lo siguiente:

Creé una página de menú en el generador de interfaces (solo una vista con un botón)

CoreDataBooksAppDelegate.h ahora se ve así:

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

El CoreDataBooksAppDelegate.m tiene este aspecto:

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

El resto de CoreDataAppDelegete.m permanece sin cambios.

En el MenuViewController cuando se hace clic en el botón, se realiza la siguiente acción:

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

En IB cambié MainWindow.xib para llamar a MenuViewController en lugar de RootViewController.

Entonces, la aplicación se carga y el menú se muestra correctamente con el botón. Al hacer clic en el botón, la aplicación se bloquea dentro de viewDidLoad de RootViewController.

Se bloquea aquí:

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

En la consola recibo lo siguiente:

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

He leído sobre esta excepción, pero no sé los pasos adecuados para resolverla.

¿Fue útil?

Solución

Ok.

Colocar el siguiente código dentro de viewDidLoad de RootViewController elimina el error:

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

Encontré a alguien con un problema similar aquí en SO: texto del enlace

Como Aryeh señaló en esa publicación: " En resumen, está tratando de obtener una entidad de un objetoContext que aún no se había configurado. Por lo tanto, sus opciones son configurarlo en ese momento o hacerlo en otro lugar de la aplicación antes de que se cargue esta vista. & Quot;

Otros consejos

En applicationDidFinishLaunching: estás haciendo lo siguiente:

rootViewController.managedObjectContext = self.managedObjectContext;

Pero no veo el código donde se configura self.managedObjectContext. applicationDidFinishLaunching se llama bastante temprano. ¿Está seguro de configurar el contexto del objeto administrado?

¿Cambiaste el modelo de datos básicos? Ese error es común cuando el modelo de Core Data para una aplicación cambia sin cambiar también la base de datos SQLite subyacente, por lo que los datos almacenados y el modelo no están sincronizados.

Intente eliminar completamente su aplicación del simulador o dispositivo de prueba, luego vuelva a instalarla e intente nuevamente.

Durante mi desarrollo, no pude encontrar entidades que agregué más adelante. Lo que funcionó para mí: (Básicamente un consejo de cordura :-)

¡Desinstale la aplicación CADA VEZ que cambie el Modelo de datos!

El modelo de datos es almacenado en caché por Core Data entre las instalaciones, para garantizar que la integridad permanezca intacta. Elimine la aplicación del simulador / iPhone para poder probar sus cambios.

PD: ¿alguien sabe cómo hacer eso automáticamente?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top