iOS8 Swift: deleteRowsAtIndexPaths se bloque
Je vais avoir quelques problèmes avec la suppression d'une ligne de mon tableView dans Swift, iOS 8, Xcode 6 Beta 6. Chaque fois que j'essaie de supprimer une ligne, j'obtiens une erreur le long de la lignes de
Échec d'Assertion dans -[UITableView _endCellAnimationsWithContext:],
/SourceCache/UIKit_Sim/UIKit-3302.3.1/UITableView.m:1581 2014-08-30
20:31:00.971 Classe Directory[13290:3241692] *** fin de l'app en raison de
uncaught exception 'NSInternalInconsistencyException', la raison:
'Mise à jour incorrecte: non valides nombre de lignes dans la section 1. Le nombre de
les lignes contenues dans un article existant après la mise à jour (25) doit être
égal au nombre de lignes contenues dans cette section avant de l'
mise à jour (25), plus ou moins le nombre de lignes insérées ou supprimées à partir de
cet article (0 inséré, 1 supprimés) et plus ou moins le nombre de
les lignes déplacées dans ou hors de la section (0 déplacé, 0).
J'ai lu toutes les réponses à ce problème fréquent, ici, et j'estime avoir rempli les conditions recommandées. L'élément semble être retiré à partir du modèle de données -- quand je recharge l'application, l'élément supprimé est passé de la table -- mais il semble y avoir quelques restes dans le fichier sqlite et bien sûr, les mathématiques ne fonctionne pas. La println que crache le indexPath montre la bonne Section et de la Ligne. Je suis très perplexe. Cela devrait être simple, mais je suis absent quelque chose de stupide, je suis sûr, je soupçonne que dans le modèle de données de suppression. Projet complet sur Github.
func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return fetchedResultController.sections.count
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return fetchedResultController.sections[section].numberOfObjects
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableViewMain.dequeueReusableCellWithIdentifier("CellMain", forIndexPath: indexPath) as UITableViewCell
let personForRow = fetchedResultController.objectAtIndexPath(indexPath) as Person
cell.textLabel.text = personForRow.fullName()
return cell
}
func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
return true
}
func tableView(tableView: UITableView!, editingStyleForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.Delete
}
func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
println("section and row \(indexPath.section) \(indexPath.row) ")
if (editingStyle == UITableViewCellEditingStyle.Delete) {
let personForRow : NSManagedObject = fetchedResultController.objectAtIndexPath(indexPath) as Person
context?.deleteObject(personForRow)
context?.save(nil)
tableViewMain.beginUpdates()
tableViewMain.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
tableViewMain.endUpdates()
}
Pas doublon. Les réponses qui ont été insuffisantes.
OriginalL'auteur Nate Birkholz | 2014-08-31
Vous devez vous connecter pour publier un commentaire.
Il est facile de reproduire le crash avec un Xcode Base de Données Maître-Détail d'un modèle de projet. En règle générale, lorsque vous utilisez
NSFetchedResultsController
, vous devriez vraiment utiliserNSFetchedResultsControllerDelegate
(vous avez déclaré, mais ne l'utilisez pas).Supprimer ces lignes dans votre
tableView:commitEditingStyle:forRowAtIndexPath:
méthode:Et ajoutez ces lignes à votre viewController classe:
Cela devrait résoudre votre problème.
Pouah, il est tard et j'ai collé le code dans le milieu de la commitEditingStyle fonction plutôt qu'à la racine de la viewController classe. Cela a parfaitement fonctionné. Bien obligé.
Ce n'était pas exactement mon problème. Le problème avec mon code était que tableView nombre de lignes de la fonction n'était pas la mise à jour de son compte après la suppression de la ligne. Ce post m'a laissé entendre en vue d'avoir un regard sur ce morceau de mon code. Merci!!!!
OriginalL'auteur Imanou Petit
Je crois que c'est simplement un problème de mise en cache. Votre
fetchedResultController
ne va pas automatiquement récupère à nouveau vos résultats, car elle cache les résultats. Cela signifie que lorsquetableView:numberOfRowsInSection:
est appelée de nouveau, les résultats de comptage est encore de retour de 25 même si vous avez supprimé un élément.tableView:numberOfRowsInSection
en interne dans ledeleteRowsAtIndexPaths
. C'est la façon dont c'est l'impression du message d'erreur dans la première place, mais le plus important, c'est comment il vérifie que les lignes que vous tentez d'ajouter/supprimer sont réellement supprimés à partir des données.Ouais, c'est là qu'il est en train de mourir... Toutes les idées sur les détails d'une résolution? (Ma première réponse était incorrecte, j'ai ajouté plus de l'enregistrement de débogage et vous aviez raison, désolé pour l'erreur de ma part.)
il y a peut être un moyen de forcer
fetchedResultsController
de jeter son cache. Cependant, si c'était moi, je voudrais stocker les résultats dans un tableau temporaire membre et l'utiliser pour la source de données à la place. De cette façon, vous pouvez gérer le tableau (suppression de l'élément) de vous-même et vous inquiétez pas sur les détails de mise en œuvre de lafetchedResults
Il permet de charger dans un tableau, mais j'ai eu beaucoup de problèmes et mon instructeur qui a recommandé agissant directement sur le modèle de données. Je vais creuser un peu plus avec cette idée. Je vous remercie.
Je recommande l'abstraction supplémentaire qui va faire qu'il est plus facile de changer votre application à l'aide d'une source de données différente si nécessaire. Peut-être que vous voulez ajouter de la prise en charge de dropbox ou de certains autres services de synchronisation dans l'avenir. Il est normalement une bonne idée d'avoir une couche d'abstraction entre les contrôleurs et la façon dont vous êtes réellement le stockage de l'information.
OriginalL'auteur drewag