2010-09-02 5 views
1

J'ai des problèmes avec ma coredata sqlite DB, qui héberge un livre DB. Après un crash, un utilisateur rencontre le problème, que les données ne sont plus correctement affichées dans sa tableview.coredata sqlite malformé DB

Cela est dû au fait que la méthode performFetch renvoie une erreur:

[NSFetchedResultsController deleteCacheWithName:nil]; 
if (![[self fetchedResultsController] performFetch:&error]) { 
     //NSArray *array = [[self fetchedResultsController] fetchedObjects]; 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
#ifdef DEBUG 
     abort(); 
#endif 
    } 

qui se traduit par ce message d'erreur:

Erreur non résolue erreur Domaine = NSCocoaErrorDomain Code = 134060 « Le couldn de fonctionnement Ne pas être terminé. (Cocoa error 134060.) "UserInfo = 0x1dff80 {reason = L'objet récupéré à l'index 312 a un nom de section en désordre 'Z. Les objets doivent être triés par nom de section '}, { reason = "L'objet récupéré à l'index 312 a un nom de section en désordre' Z. Les objets doivent être triés par nom de section '";

Lorsque j'examine le fichier sqlite avec 'SQLite Database Browser 2.0 b1', les attributs de chaque entité semblent convenir.

Lorsque je supprime certaines des entités mentionnées tout fonctionne à nouveau correctement.

Je voudrais savoir comment je peux savoir exactement ce qui ne va pas avec les entités mentionnées et corriger cela, afin que l'utilisateur puisse à nouveau utiliser ses données. Bien sûr, je veux corriger le bug qui provoque la base de données mal formée, mais ce n'est pas le cas dans ce post.

Quelqu'un a-t-il des indices sur ce que je pourrais voir ou ce qui pourrait être malformé dans ma base de données ou sur le "nom d'une section hors service"?

C'est le code pour mon fetchedResultsController:

- (NSFetchedResultsController *)fetchedResultsController { 

    if (fetchedResultsController != nil) { 
     return fetchedResultsController; 
    } 


    // Create the fetch request for the entity. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity; 
    entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:[[GlobalData sharedInstance] managedObjectContext]]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:10]; 

    //set searchPredicate 
    NSPredicate *predicate = nil; 
    if (self.bibList != nil) { 
     predicate = [NSPredicate predicateWithFormat:@"ANY BibLists.name LIKE %@", self.bibList.name];  
    } 

    if (predicate) { 
     [fetchRequest setPredicate:predicate]; 
    } 


    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor; 
    NSString *sortDescriptorString = nil;  
    sortDescriptorString = @"title"; 
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortDescriptorString ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

    NSString *sectionNameKeyPath = nil; 
    sectionNameKeyPath = @"uppercaseFirstLetterOfTitle"; 

    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController; 
    aFetchedResultsController = [[NSFetchedResultsController alloc] 
          initWithFetchRequest:fetchRequest 
          managedObjectContext:[[GlobalData sharedInstance] managedObjectContext] 
          sectionNameKeyPath:sectionNameKeyPath 
          cacheName:@"Bibliography"]; 

    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    [aFetchedResultsController release]; 
    [fetchRequest release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 

    return fetchedResultsController; 
}  

Merci b00tsy

+0

Incluez votre code de requête d'extraction et tous les descripteurs de tri ajoutés. – falconcreek

+0

Est-ce que 'uppercaseFirstLetterOfTitle' est une propriété transitoire ou persistante? Existe-t-il une entrée commençant par une lettre minuscule dans 'title'? – falconcreek

+0

'uppercaseFirstLetterOfTitle' est un attribut transitoire. il y a des entités qui ont des lettres minuscules et des lettres non-ascii dans 'title' – b00tsy

Répondre

1

Je pense que ce qui se passe ici est que votre magasin SQL est corrompu et/ou vous avez un sectionNameKeyPath inhabituel.

Le schéma de données de base préfixe tous les noms de colonne SQL avec Z, de sorte qu'une erreur d'un nom de 'Z suggère une table SQL endommagée. Pour tester cela, exécutez la requête d'extraction directement au lieu d'utiliser le contrôleur de résultats récupérés et voyez si vous pouvez récupérer tous les objets.

Si vous ne pouvez pas, le magasin SQL est endommagé. Très probablement, un composant de table est simplement le nom 'Z au lieu de quelque chose comme ZAttributeName. Vous devrez éditer le SQL directement mais c'est difficile à cause du schéma privé personnalisé. Voir this post pour avoir une idée de ce qu'il faut chercher. Il n'y a pas d'outils pour le faire car la corruption du magasin est si rare.

Si la récupération fonctionne, le problème est que le sectionNameKeyPath est transmis au contrôleur de résultats récupérés. À l'heure actuelle, il semble que vous ayez un attribut d'entité avec la première lettre de l'attribut title. (Ceci est redondant parce que, par défaut, le FRC retournera automatiquement les sections alphabétiques basées sur n'importe quel attribut de chaîne.) Essayez de changer le sectionNameKeyPath en juste le nom de l'attribut title (le plus probable "title"). Dans tous les cas, il suffit de se passer complètement de l'attribut uppercaseFirstLetterOfTitle.

+0

l'attribut majusculeFirstLetterOfTitle * peut * être utile lorsque vous travaillez avec de grands ensembles de données comme suggéré par Apple dans la vidéo WWDC Session 118. Possibilité d'améliorer les performances avec une complexité supplémentaire. (Ce message est une preuve claire.) – falconcreek

+0

Cela explique pourquoi je continue à voir cela. Je pense que beaucoup de gens l'utilisent inutilement. Ce n'est pas une technique pour les novices. – TechZen

+0

Merci pour votre réponse. Le fetchRequest direct sur le managedObjectContext a fonctionné. Le problème était qu'il y avait des titres en minuscules et des titres non-ascii disponibles qui ont causé le problème mentionné par falconcreek. La dispense de 'uppercaseFirstLetterOfTitle' n'est pas une option, car je ne veux pas de section pour chaque titre. Je veux une section pour chaque 'uppercaseFirstLetterOfTitle' seulement. – b00tsy

1

La déclaration suivante dans les documentation fait allusion à l'erreur.

If this key path is not the same as that specified by the first sort descriptor in fetchRequest, they must generate the same relative orderings.

Il semble que l'article à l'index 312 ne soit pas dans la bonne section lors du tri sur titre seul. Cela peut être dû au fait que la propriété title commence par une lettre qui n'est pas une lettre ou une lettre minuscule. Le tri lexical le mettrait après la section Z, mais la valeur de la majusculeFirstLetterOfTitle de l'élément n'est pas 'Z'. À titre de suggestion, essayez d'ajouter un descripteur de tri sur le uppercaseFirstLetterOfTitle en tant que premier descripteur de tri, puis ajoutez le descripteur de tri sur title.

+0

Merci pour votre réponse. C'est en minuscules que les titres sont exactement le problème. Mais comme 'uppercaseFirstLetterOfTitle' est une propriété transitoire, je n'ai pas réussi à l'utiliser comme un descripteur de tri. Devrais-je le rendre persistant ou existe-t-il une autre option pour gérer ce cas? Ou devrais-je vérifier sur la génération de titre qu'il commence avec une lettre majuscule? – b00tsy

+0

Selon TechZen, vous pouvez supprimer 'uppercaseFirstLetterOfTitle'. Le comportement par défaut de passer le '@ title' à' sectionNameKeyPath: 'fournira le comportement que vous voulez. Ce n'est pas équivalent à "grouper par titre" dans SQL – falconcreek

+0

bien que cela mène à une section pour chaque titre unique, où je voudrais avoir une section pour chaque première lettre seulement. Ou suis-je manquant le s.th. en dehors? – b00tsy