Ошибка утверждения в - [UITableView _endCellAnimationsWithContext:]

Надеюсь, это будет быстрое решение. Я пытался выяснить ошибку, которую я продолжаю получать. Ошибка указана ниже, а appdelagate - ниже.

Любая помощь приветствуется.

Спасибо

2012-04-12 21:11: 52.669 Chanda [75100: f803] --- Ошибка утверждения в -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:10372012-04-12 21:11: 52.671 Chanda [75100: f803] --- Завершение приложения из-за неперехваченного исключения 'NSInternalInconsistencyException', причина: 'Неверное обновление: недопустимое количество строк в разделе 0. Количество строк в существующем разделе после обновления (2) должно быть равно количеству строк, содержащихся в этом разделе перед обновлением (2), плюс или минус количество строк, вставленных или удаленных из этого раздела (1 вставлено, 0 удалено) и плюс или минус количество строк, перемещенных в или из этой секции (0 перемещен, 0 перемещен).

#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

Ответ 1

Я не вижу причины для того, чтобы вы показали нам эту часть кода. Ваша ошибка должна быть связана с этой частью вашего кода. Я предполагаю

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

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

Возможно, вы ошибаетесь в одном из этих методов источника данных. В настоящее время невозможно сказать, что именно не так, но я предполагаю, что это может быть что-то вроде: вы говорите о представлении таблицы в numberOfRowsInSection, вы хотели бы иметь n строк, зарезервированных и настроенных, а в cellForRowAtIndexPath вы тогда обрабатываете только n - 1 строка, например.

Извините, что этот ответ не может быть таким точным, каким он должен быть. Если вы покажете нам свою реализацию вашего источника данных, было бы гораздо легче сказать, что происходит.

Ответ 2

Как и Sun Tzu сказал: лучше побеждать, не сражаясь. В моем случае всякий раз, когда я вижу такое сообщение об ошибке (т.е. Несоответствие между добавленными строками и т.д.). Я даже не отлаживаю ничего. Я просто не делаю дополнительный вызов, где я перезаряжаю строки и т.д., Что 99% случаи, когда эта ошибка происходит.

Это распространенный сценарий, когда эта ошибка происходит: у меня есть UINavigationController, и она имеет UITableView, когда я нажимаю на строку, она нажимает новый UITableView и так далее. Эта ошибка всегда случается со мной, когда я выхожу последним UITableView и возвращаюсь к UITableView до этого, в этот момент я делаю ненужный вызов функции loadIt, которая в основном вставляет строки и переадресовывает UITableView,

Причина этого в том, что я ошибочно помещаю функцию loadIt в viewDidAppear:animated, а не viewDidLoad. viewDidAppear:animated вызывается каждый раз, когда отображается UITableView, viewDidLoad вызывается только один раз.

Ответ 3

При удалении строк помните, что он также проверяет разделы при обновлении:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

Если вы хотите удалить строку, которая является последним элементом в разделе, вам нужно удалить весь раздел (в противном случае это может привести к ошибке раздела и исключить это исключение).

Ответ 4

Не забудьте обновить массив, который определяет numberOfRowsInSection. Он должен быть обновлен до того, как вы анимируете и удалите

Мы проверяем, будет ли количество строк в секции равным 1, потому что нам нужно будет удалить весь раздел.

Поправьте меня, если кто-нибудь сможет сделать этот ответ более ясным.

[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];

Ответ 5

Я помещаю каждый элемент раздела в разделенные массивы. Затем поместите их в другой массив (arrayWithArray). Мое решение здесь для этой проблемы:

[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];

Ответ 6

У меня была такая же ошибка.

Я использовал следующие строки

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

чтобы зарегистрировать nib в методе viewDidLoad, так как у меня был другой значок, который также был связан с одним и тем же классом. Следовательно, линия

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

возвращал ноль, если я не зарегистрировал nib в viewDidLoad.

Моя проблема заключалась в том, что я забыл установить идентификатор в инспекторе атрибутов для моего файла "CustomNib.xib" и "CustomNib ~ iphone.xib". (Или, точнее, я забыл нажать enter после ввода идентификатора в инспекторе атрибутов в XCode, чтобы новое имя не удалось сохранить.)

Надеюсь, что это поможет.

Ответ 7

Я имел ту же ошибку, которая при попытке с помощью [tableView reloadData] работала нормально. Ошибка была в строке

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

Когда я попытался проверить значения indexPath, они были неверны по мере необходимости.

Я исправил его, изменив значения в indexPathsArray.

Надеюсь, что это поможет.

Ответ 8

Если вы используете NSFetchedResultsController как я и обновляете данные в фоновом потоке, не забудьте начинать и заканчивать обновления в делегате:

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

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

Ответ 9

У меня была такая же проблема с базой данных Core. Если вы используете много FRC, вам просто нужно перезагрузить tableview внутри каждого условия в numberOfSectionsInTableView.

Ответ 10

Я просто это случилось со мной, используя Swift и хранилище данных с поддержкой FRC для управления информацией. Добавление простой проверки в операцию удаления для оценки текущего indexPath.section позволило мне избежать постороннего вызова. Я думаю, я понимаю, почему эта проблема возникает... В основном я загружаю сообщение в верхнюю строку всякий раз, когда мой набор данных пуст. Это создает исключение из одной проблемы, поскольку существует строка faux.

Мое решение

... 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)

            }

Ответ 11

Его может быть одним из методов протокола UITableViewDataSource

Для

- tableView:numberOfRowsInSection:

он должен возвращать целое число, равное сумме или результату

-insertRowsAtIndexPaths:withRowAnimation: и/или -deleteRowsAtIndexPaths:withRowAnimation:

Для

- numberOfSectionsInTableView:

он должен возвращать целое число, равное сумме или результату

-insertRowsAtIndexPaths:withRowAnimation: и/или -deleteSections:withRowAnimation:

Ответ 12

Просто проверьте, что вы вызываете [yourTableView reloadData]; после изменения массива значений.