Question

J'ai un NSFetchedResultsController comme ma source de données et et je mets en œuvre dans NSFetchedResultsControllerDelegate mon habitude UITableViewController. J'utilise sectionNameKeyPath pour briser mon jeu de résultats en plusieurs sections.

Dans un de mes méthodes, j'ajoute deux objets au contexte, qui sont tous dans une nouvelle section. Au moment où je sauve les objets, les méthodes de délégués sont appelés correctement. L'ordre des événements:

// -controllerWillChangeContent: fires
[self.tableView beginUpdates]; // I do this

// -controller:didChangeSection:atIndex:forChangeType: fires for section insert
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];

// -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath fires many times
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                withRowAnimation:UITavleViewRowAnimationFade]; // for each cell

// -controllerDidChangeContent: fires after all of the inserts
[self.tableView endUpdates];  // <--- Where things go terribly wrong!!!

Le dernier appel, "endUpdates", l'application se bloque toujours avec:

Serious application error.  Exception was caught during Core Data change processing:
[NSCFArray objectAtIndex:]: index (5) beyond bounds (1) with userInfo (null)

Il semble que les mises à jour de la table ne sont pas en phase avec les données NSFetchedResultsController en quelque sorte, et les choses exploser. Je suis la documentation sur NSFetchedResultsControllerDelegate, mais il ne fonctionne pas. Quelle est la bonne façon de le faire?

Mise à jour: J'ai créé un projet de test qui présente ce bug. Vous pouvez le télécharger à l'adresse: NSBoom.zip

Était-ce utile?

La solution

Suivi par l'application, je note didChangeSection est appelée en premier, qui insère une section entière -. Et didChangeObject est appelée à plusieurs reprises

Le problème est que dans didChangeSection vous insérez une section entière, puis à droite après avant l'affichage du tableau est mis à jour vous ajoutez des objets à cette même section. Ceci est essentiellement un cas de mises à jour qui se chevauchent ... (même pas le droit dans un début / fin bloc de mises à jour).

Si vous commentez l'insert d'objet individuel, tout cela fonctionne:

 case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

Si vous commentez l'insert section :, il ne fonctionne pas - mais j'ai eu moins de chance avec insertRowsInSections de travail tout le temps, et il peut bien être parce qu'il n'y a pas encore de section (dont je suis sûr est pourquoi vous insérez la section pour commencer). Vous devrez peut-être détecter tous les cas pour effectuer des insertions avec la granularité droite.

En général, j'ai eu beaucoup plus de chance rechargeant et en insérant des sections entières de lignes, la vue du tableau me semble très fiddly à ceux qui travaillent autour. Vous pouvez également essayer UITableViewRowAnimationNone qui semble fonctionner avec succès plus souvent.

Autres conseils

Je vais avoir le même problème. Je trouve que didChangeSection se déclenche à deux reprises. Une fois que lorsque vous créez l'objet pour l'insertion, et une fois que lorsque vous enregistrez réellement. Pour moi, il ne devrait pas appeler didChangeSection jusqu'à sauver est appelé. Ou à tout le moins, willChangeSection serait appelé à la création de l'objet, et didChangeSection appelé quand il est enregistré.

Maintenant, je suis à la recherche dans la méthode d'observation NSManagedObjectContextDidSaveNotification. Ce ne fait pas partie du protocole NSFetchedResultsControllerDelegate, mais vous pouvez vous inscrire pour le recevoir. Peut-être que cela ne sera appelé quand je l'appelle réellement sauver et non pas avant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top