2010-03-14 5 views
2

J'ai construit une application depuis 1 mois en utilisant NSFetchedResultsController et je testais l'application sur le SDK 3.1.2. Le problème est que j'ai utilisé NSFetchedResultsController partout dans mon application et travaillait sur la version 3.1.2 du SDK, maintenant mon client dit que je devrais le rendre compatible avec la version 3.0 et la date limite est presque là.NSFetchedResultsController me rend fou

Mais se bloque chaque fois que je change un objet géré par le contrôleur, l'application plante avec des erreurs très étranges.

Le problème se produit lors de la suppression du dernier objet dans une section et quand un changement fait aimer un objet à une autre section. J'ai utilisé un exemple de code de "More iPhone 3 Development Tackling iPhone SDK 3" par Dave Mark et Jeff LaMarche. J'ai également inclus quelques modifications de link text

Voici un exemple de sortie de la console lorsque l'application plante.

*** en raison de l'application Mettre fin exception uncaught 'NSInternalInconsistencyException', motif: « mise à jour invalide: numéro non valide de sections. Le nombre de sections contenues dans la vue de table après la mise à jour (1) doit être égal au nombre de sections contenues dans la vue de tableau avant la mise à jour (2), plus ou moins le nombre de sections insérées ou supprimées (2 insérées, 0 supprimé). ' 14/03/2010 16: 23: 29,758 Instaproofs [5879: 207] Stack: ( 807902715, 7364425, 807986683, 811271572 , 815059090, 815007323 , 211023, 4363331 , 810589786, 807635429, 810579728, 3.620.573, 3.620.227 , 3.614.682, 3.609.719 , 27337, 810595174, 807686849 , 807683624, 839142449 , 839142646,Si je savais que NSFetchedResultsController est si bogué, je ne l'aurais jamais utilisé. Donc, en principe, j'ai besoin de mon NSFetchedResultsControllerDelegate pour fonctionner correctement sur les SDK 3.0 et ci-dessus.

Ce serait de sauver la vie si quelqu'un m'aider à comprendre ce que je fais mal.

Répondre

5

Il apparaît à partir de vos messages d'erreur que vous insérez des sections dans la table lorsque vous devriez les supprimer. Votre tableView dataSource ne fournit qu'une section après les mises à jour, même si vous avez demandé à tableView d'attendre un total de quatre sections.

Je ne pense pas que NSFetchedResultsController soit buggé, mais plutôt qu'il soit difficile à implémenter en dehors des cas d'utilisation simples. Vos plantages sont presque certainement dus à votre contrôleur: didChangeObject: atIndexPath: forChangeType: méthode de délégué newIndexPath. La clé de la réussite de l'implémentation de cette méthode (du moins dans mon expérience) est de garder à l'esprit que les types de changement sont à la fois pilotés par un objet et indexPath. Cela rend les «mises à jour» et les «déplacements» difficiles d'un point de vue conceptuel.

Considérez la situation dans laquelle un objet géré est modifié de telle sorte qu'il est trié sous un nouveau nom de sectionNameKeyPath.Conceptuellement, nous considérons que l'objet a été "déplacé" dans une nouvelle section puisque le récupérateur fetchedResultsController le trie maintenant sous un nouvel en-tête dans la tableView. Si le paramètre indexPath de l'objet ne change pas, le paramètre fetchedResultsController considère qu'il s'agit d'une "mise à jour" et non d'un "déplacement".

Ce qui est pire est que même si l'objet géré qui a changé conserve toujours le même indexPath, d'autres objets dans le fetchedResultsController peuvent maintenant avoir de nouveaux indexPaths parce qu'ils ont été renversés par le changement. Cela signifie que vous devrez gérer manuellement les insertions de section et les suppressions de section dans la section "mise à jour" de votre méthode déléguée. Des problèmes similaires devront être traités dans la section "move" de votre méthode de délégué.

Sans chercher à l'expliquer en tant de mots, le correctif de LaMarche tente de résoudre ce problème d'une manière générique qui accepte autant de cas d'utilisation que possible. En essayant de comprendre le problème en fonction de votre cas d'utilisation, vous pourriez réduire considérablement la complexité du code utilisé par LaMarche. Concentrez-vous spécifiquement sur les sections "update" et "move" de votre méthode de délégué, car ce sont les coupables les plus probables de votre problème.

+0

Remarque: Il existe un bogue dans la version 3.0 de NSFetchedResultsController que je connais et il est mentionné dans la documentation de référence de classe. Le bug est seulement un problème si vous ne spécifiez pas un sectionNameKeyPath. Vous souhaiterez peut-être implémenter la solution de contournement fournie dans la documentation, par mesure de sécurité. – glorifiedHacker

+1

Le message ci-dessus est extrêmement utile. J'ai le même problème que l'affiche originale. J'ai constaté que le rechargement des données après un changement de - (void) de commande: (NSFetchedResultsController *) de commande didChangeObject: (id) anObject atIndexPath: (NSIndexPath *) indexPath \t forChangeType: (NSFetchedResultsChangeType) de type \t newIndexPath: (NSIndexPath *) newIndexPath fonctionne la plupart du temps, mais pas dans 100% des cas. Je ne sais pas à quel point c'est important; mais j'espère que cela aide tous ceux qui tombent sur ce post. –