32 votes

Coredata - "NSObjectInaccessibleException - CoreData n'a pas pu résoudre une erreur"

Je suis nouvelle Base de données et encore de comprendre les écrous et boulons, et cette erreur a été mise sur écoute moi pendant des heures et je ne peux pas l'air de trouver une solution. Toute aide est grandement appréciée.

Le problème, c'est comme ça

J'ai deux points de vue qui extraire des données à partir du serveur et la mise à Jour de l'INTERFACE utilisateur. J'ai mis en place le flux de cette façon

vue1 -> Envoyer HTTP Req. à partir du Serveur - Recevoir de Rappel -> Enregistrer de Données De Coredata -> Lire à Partir de Base de Données et l'affichage sur l'INTERFACE utilisateur (rappel et l'enregistrement/la lecture de Coredata arriver dans ViewController)

vue2 -> Envoyer HTTP Req. à partir du Serveur - Recevoir de Rappel -> Enregistrer de Données De Coredata -> Lire à Partir de Base de Données et l'affichage sur l'INTERFACE utilisateur (rappel et l'enregistrement/la lecture de Coredata arriver dans ViewController)

Vue 2 répète ce processus toutes les 3 secondes, c'est un rafraîchissement automatique de l'écran.

Le problème est que chaque fois que j'essaie de basculer entre les vues 1 et 2, très vite, il bloque l'application avec l'erreur ci-dessus. Si j'attends quelques secondes sur chaque vue (attendre que les données soient récupérées à partir du serveur), il fonctionne très bien. Suis-je en train de faire quelque chose de mal, que dois-je modifier?

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

C'est l'exemple de code que j'utilise, même Vue2 a la même rappels et suit le même flux.

Edit 1 J'ai oublié de mentionner plus tôt, j'ai toujours l'erreur en saveToCoreData méthode. Aussi, plus qu'une chose à noter est que Si je supprime le code pour supprimer des objets tout fonctionne très bien (j'ai besoin de supprimer toutes les données existantes à partir de la table avant de me sauver la mise à jour des données). Pas sûr de ce qui se passe si.

42voto

casademora Points 15214

La raison du retrait de votre suppression du code du travail est parce que vous êtes en train de supprimer les données dans le système de persistance sans mettre à jour l'autre point de vue, qui n'a toujours géré les instances d'objet lié pour que les données restent en mémoire. Rappelez-vous, tandis que la Base de Données concerne les objets, chaque objet doit avoir une ligne dans la base de données derrière. Lorsque vous supprimez cette ligne, Base de Données se met en colère.

Donc, pour résoudre ce problème, et encore suppression de vos données, vous devriez avoir votre point de vue écoutez NSManagedObjectContextWillSaveNotification et/ou NSManagedObjectContextDidSaveNotification et les notifications de mise à jour de vos points de vue avec la plus à jour des versions de données dans votre magasin. C'est à ce stade, vous devriez jeter loin de toute Base de Données des objets de vos points de vue sont maintenant sur, et les recharger à partir de la boutique.

3voto

user216661 Points 155

Je viens de résoudre cette erreur dans mon code. Il semble que mon cache ait été corrompu d'une manière ou d'une autre. J'ai utilisé la suggestion de Christopher Pickslay et Keil Gillard de supprimer ou de renommer mon cache, et le tour est joué, résolu. Index NSFetchedResultsController au-delà des limites

0voto

David DelMonte Points 1369

Pour info, hier, j'ai eu le même message d'erreur. J'ai vérifié dans une version live de l'application, et il était toujours là. aïe.

J'ai couru à travers toutes les permutations de l'ajout d'informations à la base de données de la pile jusqu'à ce que le crash s'est produit.

J'ai alors regardé le fichier sqlite à partir de l'application dans le simulateur de la bibliothèque à l'aide de SqliteManager. J'ai trouvé une erreur de données dans une table. Cela avait eu lieu il y a un starter db utilisée la première fois que l'application a été exécuté. L'erreur était dans le starter db.

A couru de nouveau l'application, l'analyse de chaque champ dans chaque tableau. Trouve plusieurs occurrences. Je me souviens de la lecture de cette question, et pensé que peut-être quelqu'un d'autre pourrait bénéficier de mon erreur.

-1voto

Damien Points 1576

Votre libération excessive de fetchedObjects dans votre méthode readFromCoreData . executeFetchRequest vous renverra de toute façon des objets libérés automatiquement. Lorsque la boucle d'exécution en cours a terminé son exécution (lorsque vous sautez des vues), elle tente de libérer les objets deux fois (en supposant que vous n'avez pas utilisé vos propres pools de libération automatique).

Je changerais

 return [fetchedObjects autorelease]; 
 

à

 return fetchedObjects;
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X