Pregunta Coredata - "NSObjectInaccessibleException - CoreData no pudo cumplir una falla"


Soy nuevo en los datos del núcleo y sigo descifrando las tuercas y tornillos, y este error me ha estado molestando durante horas y no puedo encontrar una solución. Cualquier ayuda es muy apreciada.

El problema es como esto

Tengo dos vistas que recogen datos del servidor y actualizan la UI. He configurado el flujo de esta manera

view1 -> Enviar HTTP Req desde el servidor - Recibir devolución de llamada -> Guardar datos en Coredata -> Leer desde Core Data y mostrar en la interfaz de usuario (devolución de llamada y guardar / leer Coredata en ViewController)

view2 -> Enviar HTTP Req desde el servidor - Recibir devolución de llamada -> Guardar datos en Coredata -> Leer desde datos básicos y mostrar en la interfaz de usuario (devolución de llamada y guardar / leer datos básicos en ViewController)

Ver 2 repite este proceso cada 3 segundos ya que es una pantalla de actualización automática.

El problema es que cada vez que intento cambiar entre las vistas 1 y 2 muy rápido, se bloquea la aplicación con el error anterior. Si espero unos segundos en cada vista (espere a que se obtengan los datos del servidor), funciona bien. ¿Estoy haciendo algo mal? ¿Qué debo modificar?

- (void) refreshData {
    [super refreshData];
    [[UserDataFactory sharedSingleton] refreshLoggedInUserDataAndRespondTo:self user:self.user];
}

- (BOOL) refreshDataCallback:(QExtendedHTTPOperation*)responseOperation {
    [self saveToCoreData: responseOperation.responseArray];
    NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:[self readFromCoreData]];
    [self setData: tmp];
    [tmp release];
    [self.tableView reloadData];
    return YES;
}

- (void) saveToCoreData:(NSArray *) responseArray{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    [fetchRequest release];

    for (NSManagedObject *managedObject in items) {
            [self.managedObjectContext deleteObject:managedObject];
    }

    for (int i=0; i<[responseArray count]; i++) {
            CoreView1 *coreView1_ = [NSEntityDescription insertNewObjectForEntityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
            coreView_.id = [[responseArray objectAtIndex:i] id];    
            [self.managedObjectContext insertObject:coreView1_];
    }
    [self saveContext:self.managedObjectContext];
}

- (NSArray *) readFromCoreData{ 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSMutableArray *fetchedObjects = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    [fetchRequest release];
    return [fetchedObjects autorelease];
}

Este es el código de muestra que estoy usando, incluso View2 tiene las mismas devoluciones de llamada y sigue el mismo flujo.

Editar 1 Olvidé mencionar esto antes, siempre obtengo el error en el método saveToCoreData. Además, una cosa más a tener en cuenta es que si elimino el código para eliminar objetos todo funciona bien (necesito eliminar todos los datos existentes de la tabla antes de guardar los datos actualizados). Sin embargo, no estoy seguro de lo que está pasando.


32
2018-04-08 06:30


origen


Respuestas:


La razón por la que eliminar su código de eliminación hace que funcione es porque está eliminando los datos en el almacén persistente sin actualizar la otra vista que todavía tiene instancias de objetos administrados vinculadas a los datos que todavía están en la memoria. Recuerde, mientras Core Data trata con objetos, cada objeto tiene que tener una fila en la base de datos detrás de él. Cuando borras esa fila, Core Data se enoja.

Por lo tanto, para solucionar este problema y aún eliminar sus datos, debe tener sus vistas para escuchar NSManagedObjectContextWillSaveNotification y / o NSManagedObjectContextDidSaveNotification notificaciones y actualice sus vistas con las versiones más actualizadas de datos en su tienda. Es en este punto que debe descartar cualquier objeto de Datos de núcleo que sus vistas retengan y volver a cargarlos desde la tienda.


42
2018-04-19 21:26



Acabo de resolver este error en mi código. Parece que mi caché estaba corrupta de alguna manera. Utilicé la sugerencia de Christopher Pickslay y Keil Gillard de eliminar o cambiar el nombre de mi caché, y listo, resuelto. NSFetchedResultsController index beyond bounds


3
2018-01-04 00:52



Para información, ayer, tuve el mismo error. Revisé una versión en vivo de la aplicación, y todavía estaba allí. ¡Ay!

Revisé todas las permutaciones de agregar información a la pila de datos centrales hasta que se produjo el bloqueo.

Luego miré el archivo sqlite desde la aplicación en la biblioteca del simulador usando SqliteManager. Encontré un error de datos en una tabla. Esto ocurrió porque hay un DB de inicio utilizado la primera vez que se ejecutó la aplicación. El error fue en el inicio db.

Vuelve a ejecutar la aplicación y prueba cada campo de cada tabla. Encontré varias más ocurrencias. Recuerdo haber leído esta pregunta, y pensé que tal vez alguien más podría beneficiarse de mi error.


0
2017-09-29 11:54



Su exceso de liberación fetchedObjects en tus readFromCoreData método. executeFetchRequest regresará a los objetos liberados automáticamente de todos modos. Cuando el bucle de ejecución actual terminó de ejecutarse (cuando está saltando de vistas), intenta liberar los objetos dos veces (suponiendo que no haya utilizado sus propios grupos de liberación automática).

Yo cambiaría

return [fetchedObjects autorelease]; 

a

return fetchedObjects;

-1
2018-04-08 06:42