web-dev-qa-db-fra.com

Échec d'assertion dans - [UITableView _endCellAnimationsWithContext:]

Espérons que ce sera une solution rapide. J'ai essayé de comprendre l'erreur que je continue à avoir. L'erreur est listée ci-dessous et l'appdelagate est en dessous.

Toute aide est appréciée.

Merci

2012-04-12 21: 11: 52.669 Chanda [75100: f803] --- Échec de l'assertion dans -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037 2012-04-12 21: 11: 52.671 Chanda [75100: f803] --- Application terminée en raison d'une exception non capturée 'NSInternalInconsistencyException', raison: 'Mise à jour non valide: nombre de lignes non valide dans la section 0. Nombre de lignes contenues dans une section existante après la mise à jour (2) doit être égale au nombre de lignes contenues dans cette section avant la mise à jour (2), plus ou moins le nombre de lignes insérées ou supprimées de cette section (1 insérée, 0 supprimé) et plus ou moins le nombre de rangs entrés ou sortis de cette section (0 déplacé, 0 déplacé). '

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize databaseName,databasePath; 

- (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
    self.databaseName = @"Customers.db";

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDir = [documentPaths objectAtIndex:0];
    self.databasePath = [documentDir stringByAppendingPathComponent:self.databaseName];
    [self createAndCheckDatabase];

    return YES;
}

- (void)createAndCheckDatabase {
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    success = [fileManager fileExistsAtPath:databasePath];

    if (success) return; 

    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];

    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}

@end
86
Scubadivingfool

Je ne vois pas pourquoi vous voudriez nous montrer cette partie du code. Votre erreur doit être connectée à cette partie de votre code, je suppose

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

Vous faites probablement une erreur dans l'une de ces méthodes de source de données. Actuellement, il est impossible de dire exactement ce qui ne va pas, mais je suppose que cela pourrait ressembler à quelque chose comme ceci: Vous indiquez la vue sous forme de table dans la variable numberOfRowsInSection pour laquelle vous souhaitez que n soit réservé et configuré, puis dans la variable cellForRowAtIndexPath, vous ne gérez que n - 1 lignes par exemple.

Désolé que cette réponse ne puisse pas être aussi précise qu'elle devrait l'être. Si vous nous montrez votre implémentation de votre source de données, il serait beaucoup plus facile de savoir ce qui se passe.

42
pbx

Comme Sun Tzu a dit : c'est mieux de gagner sans se battre. Dans mon cas, chaque fois que je vois ce type de message d'erreur (différence entre les lignes ajoutées supprimées, etc.). Je ne débogue même rien. J'évite simplement de passer cet appel supplémentaire dans lequel je recharge les lignes, etc. les cas où cette erreur se produit.

Il s'agit d'un scénario courant dans lequel ce bogue se produit: j'ai une UINavigationController et elle a une UITableView; lorsque je clique sur une ligne, une nouvelle UITableView est poussée, etc. Cette erreur m’arrive toujours lorsque je saute la dernière UITableview et que je retourne à la UITableView précédente, c’est à ce stade que je passe un appel inutile à la fonction loadIt qui insère les lignes et relance la UITableView

Cela s’explique par le fait que j’ai placé par erreur ma fonction loadIt dans viewDidAppear:animated plutôt que viewDidLoad. viewDidAppear:animated est appelé à chaque fois que la UITableView est affichée, viewDidLoad n'est appelée qu'une fois.

26
abbood

Lors de la suppression de lignes, rappelez-vous qu'il vérifie également les sections lors de la mise à jour, dans:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

Si vous souhaitez supprimer une ligne qui est le dernier élément d'une section, vous devez supprimer toute la section (sinon, le nombre de sections pourrait être incorrect et renvoyer cette exception).

24
Olof_t

N'oubliez pas de mettre à jour votre tableau qui détermine numberOfRowsInSection. Il doit être mis à jour avant d'animer et de supprimer

Nous vérifions si le nombre de lignes dans la section est égal à 1 car nous devrons supprimer la section entière.

Corrigez-moi si quelqu'un peut clarifier cette réponse.

[self.tableView beginUpdates];
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {

   [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
} else {

   [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
[self.tableView endUpdates];
6
love2script12

Je mets chaque section des éléments dans des tableaux séparés. Ensuite, placez-les dans un autre tableau (arrayWithArray). Ma solution ici pour ce problème:

[quarantineMessages removeObject : message];
[_tableView beginUpdates];
if([[arrayWithArray objectAtIndex: indPath.section] count]  > 1)
{
    [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indPath] withRowAnimation:UITableViewRowAnimationBottom];
}
else
{
    [_tableView deleteSections:[NSIndexSet indexSetWithIndex:indPath.section]
              withRowAnimation:UITableViewRowAnimationFade];
}
[_tableView endUpdates];
4
Khwarezm Shah

J'ai eu la même erreur qui, en essayant avec [tableView reloadData], fonctionnait bien. L’erreur était en réalité dans la ligne 

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

Quand j'ai essayé de vérifier les valeurs d'indexPath, elles n'étaient pas correctes comme requis. 

Je l'ai corrigé en changeant les valeurs dans indexPathsArray.

J'espère que cela t'aides .

2
user5553647

J'ai eu la même erreur.

J'utilisais les lignes suivantes

UINib *myCustomCellNib = [UINib nibWithNibName:@"CustomNib" bundle:nil];
[tableView registerNib:myCustomCellNib forCellReuseIdentifier:@"CustomNib"];

pour enregistrer le nib dans la méthode viewDidLoad, car j'avais un nib différent qui était également associé à la même classe. Par conséquent, la ligne

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GBFBLoadingCell"];

retournait nil à moins que je n'enregistre la nib dans viewDidLoad.

Mon problème était que j'ai oublié de définir l'identifiant dans l'inspecteur d'attributs pour mon fichier "CustomNib.xib" et "CustomNib ~ iphone.xib". (Ou plus précisément, j'ai oublié d'appuyer sur Entrée après avoir saisi l'identifiant dans l'inspecteur d'attributs dans XCode, de sorte que le nouveau nom n'a pas pu être enregistré.)

J'espère que cela t'aides.

2
user1612868

Si vous utilisez une variable NSFetchedResultsController comme moi et mettez à jour des données dans un thread en arrière-plan, n'oubliez pas de commencer et de terminer les mises à jour dans le délégué:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}
1
mikeho

Cela pourrait être l’une des méthodes du protocole UITableViewDataSource

Pour 

- tableView:numberOfRowsInSection:

il devrait renvoyer un entier égal à la somme ou au résultat de 

-insertRowsAtIndexPaths:withRowAnimation: et/ou -deleteRowsAtIndexPaths:withRowAnimation:

For

- numberOfSectionsInTableView:

il devrait renvoyer un entier égal à la somme ou au résultat de 

-insertRowsAtIndexPaths:withRowAnimation: et/ou -deleteSections:withRowAnimation:

1
Ted

J'ai eu le même problème avec une base de données Core. Si vous utilisez plusieurs CRF, il vous suffit de recharger la tableview dans chaque condition dans numberOfSectionsInTableView. 

0
Privatus Privatus

Cela vient de m'arriver alors que j'utilisais Swift et un magasin de données sauvegardé par FRC pour gérer les informations. L'ajout d'une vérification simple à l'opération de suppression pour évaluer le fichier indexPath.section actuel m'a permis d'éviter un appel inutile. Je pense comprendre pourquoi ce problème se produit ... En gros, je charge un message dans la rangée du haut lorsque mon jeu de données est vide. Cela crée un problème avec un problème car il y a une fausse rangée.

Ma solution

... delete my entity, save the datastore and call reloadData on tableView
//next I add this simple check to avoid calling deleteRows when the system (wrongly) determines that there is no section.

       if indexPath.section > 0 {

        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .None)

            }
0
Tommie C.

Vérifiez simplement que vous appelez [yourTableView reloadData]; après avoir modifié le tableau de valeurs.

0
Evgeniy Kleban