2010-09-09 11 views
6

Creo que entiendo el mensaje de error: CoreData no pudo cumplir un error, pero no estoy seguro de cómo debo tratarlo.CoreData no pudo cumplir un error para cuando los objetos se actualizan mediante el servicio HTTP

Tenemos una aplicación donde utilizamos datos básicos para conservar los datos devueltos por un servicio JSON. Hoy estoy haciendo lo siguiente.

  1. Fetch objeto local de almacenamiento persistente y volver a la interfaz de usuario
  2. Pregunta servidor si el objeto se actualiza - cuando llegue la respuesta, puedo actualizar los datos básicos objeto gestionado
  3. actualización de la interfaz de usuario con el objeto actualizado

El problema es; incluso si no utilizo varios subprocesos, a veces aparece un error cuando la solicitud HTTP elimina los objetos gestionados que mi interfaz de usuario ha conservado. Intenté buscar los objetos con returnsObjectsAsFaults en NO. Pensé que podría acceder a todas las relaciones y propiedades de un objeto administrado incluso si se eliminara (siempre que mi interfaz de usuario lo hubiera retenido).

¿Cómo debo resolver este problema?

Pensé que podría usar NSManagedObjectContext por separado para leer y escribir. He hecho esta prueba:

MyAuthorMO *authorUpdate = [[MyAuthorMO alloc] init]; // I have made this init insert the object into the updateContext 
authorUpdate.firstname = @"Hans"; 
authorUpdate.lastname = @"Wittenberg"; 
authorUpdate.email = @"[email protected]"; 

NSManagedObjectContext *updateContext = [[MyCoreManager getInstance] managedObjectContext]; 

NSError *error = nil; 
[updateContext save:&error]; 

NSManagedObjectContext *readContext = [[MyCoreManager getInstance] readOnlyContext]; 

NSFetchRequest *fetchRequest = [managedObjectModel fetchRequestFromTemplateWithName:@"authorByEmail" substitutionVariables:[NSDictionary dictionaryWithObject:@"[email protected]" forKey:@"EMAIL"]]; 
[fetchRequest setReturnsObjectsAsFaults:NO]; 

NSArray *authors = [readContext executeFetchRequest:fetchRequest error:&error]; 

MyAuthorMO * readAuthor = [authors objectAtIndex:0]; 

// Delete the author with update context: 
[updateContext deleteObject:authorUpdate]; 
[updateContext save:&error]; 

NSLog(@"Author: %@ %@, (%@)", readAuthor.firstname, readAuthor.lastname, readAuthor.email); 

El registro se emite muy bien, siempre y cuando utilizo el readContext para la obtención de información. Si uso el updateContext para la búsqueda, obtengo una excepción. Esto parece prometedor, pero me temo que tendré problemas en una etapa posterior. Tarde o temprano, probablemente intente acceder a una propiedad que no se recupera por completo (un error). ¿Cómo puedo lograr el comportamiento que estoy buscando?

+0

Nick, probablemente tengas razón. He leído mis publicaciones anteriores y acepto las mejores soluciones. Gracias por tu comentario. – Andi

Respuesta

14

No debe retener los objetos gestionados que el contexto ha liberado. Deje que el contexto lo haga por usted.

El problema es que los objetos gestionados pueden existir como fallas o como objetos actualizados. Cuando conserve uno, puede retener el error que no contiene datos. Incluso si retiene el objeto real, es posible que el objeto no se comporte correctamente una vez que se haya separado de su contexto.

Para manejar su escenario, necesita un contexto para la interfaz de usuario y luego un contexto para el servidor. Después de que cualquiera de los dos contextos realice cambios, debe fusionar el contexto para garantizar que ambos se actualicen correctamente en relación con la tienda.

Su interfaz de usuario debe configurarse para reflejar el estado del modelo de datos, no debe tener partes del modelo de datos que dependan del estado de la interfaz de usuario.

+1

Estoy de acuerdo con usted, pero tengo algunas preguntas de seguimiento. No estoy conservando el MO, pero si lo uso en alguna parte, probablemente podría conservarse sin que yo lo sepa. ¿Está bien agregar un MO a NSArray o NSDictionary? Si es así, se conservará ... ¿Necesito fusionar el contexto, o podría esperar la próxima vez que obtengo el "texto de lectura"? Me temo que mis datos se corromperán si fusionar dos contextos donde el objeto que actualmente estoy renderizando se elimina (con "write" -context). – Andi

+1

No estaba claro.Quise decir que no deberías tratar de retener un objeto administrado que un contexto haya eliminado. Eso se pondrá complicado. Debe fusionar el contexto, pero deberá congelar la interfaz mientras se actualiza el modelo. Observe cómo NSFetchedResultsController maneja este problema exacto al actualizar los datos mientras los datos se muestran en una tabla. Congelar la IU generalmente pasa desapercibido para el usuario. Si tiene datos que podrían eliminarse mientras el usuario está trabajando con él, debe reconsiderar su diseño. El usuario debe controlar tales eliminaciones. – TechZen

0

Tuve el mismo problema en mi base de datos porque me refiero al objeto que no existía (porque lo eliminé con otro objeto relacionado). Mi solución fue establecer "No Acción" en mi relación.

Cuestiones relacionadas