UITableView Drag and Drop не обновляет tableView. Получение ошибки изменения строки [дубликат]

flat_list = [item for sublist in l for item in sublist]

, что означает:

for sublist in l:
    for item in sublist:
        flat_list.append(item)

быстрее, чем ярлыки, опубликованные до сих пор. (l - список сгладить.)

Вот соответствующая функция:

flatten = lambda l: [item for sublist in l for item in sublist]

Для подтверждения, как всегда, вы можете использовать модуль timeit в стандартная библиотека:

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop

Объяснение: ярлыки на основе + (включая подразумеваемое использование в sum), по необходимости, O(L**2), когда есть L подписок - как промежуточный список результатов продолжает увеличиваться, на каждом шаге создается новый объект промежуточного результирующего списка, и все элементы предыдущего промежуточного результата должны быть скопированы (а также несколько новых добавленных в конце). Таким образом (для простоты и без фактической потери общности) скажем, что у вас есть L подсписок из I предметов каждый: первые предметы I копируются взад и вперед L-1 раз, второй I - L-2 раза и т. Д .; общее количество экземпляров: I умножает сумму x для x от 1 до L, т. е. I * (L**2)/2.

Понимание списка только генерирует один список, один раз и копирует каждый элемент (из его оригинальное место проживания в списке результатов) также ровно один раз.

81
задан Randy Marsh 22 April 2012 в 18:57
поделиться

12 ответов

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

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

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

25
ответ дан abbood 23 August 2018 в 15:39
поделиться

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

0
ответ дан Evgeniy Kleban 23 August 2018 в 15:39
поделиться

Я помещаю каждый элемент раздела в разделенные массивы. Затем поместите их в другой массив (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];
4
ответ дан Khwarezm Shah 23 August 2018 в 15:39
поделиться

Не забудьте обновить массив, который определяет 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];
6
ответ дан love2script12 23 August 2018 в 15:39
поделиться

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

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}
1
ответ дан mikeho 23 August 2018 в 15:39
поделиться

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

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

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

23
ответ дан Olof_t 23 August 2018 в 15:39
поделиться

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

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

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

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

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

41
ответ дан pbx 23 August 2018 в 15:39
поделиться

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

0
ответ дан Privatus Privatus 23 August 2018 в 15:39
поделиться

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

. Для

- tableView:numberOfRowsInSection:

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

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

Для

- numberOfSectionsInTableView:

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

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

0
ответ дан Ted 23 August 2018 в 15:39
поделиться

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

My 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. 23 August 2018 в 15:39
поделиться

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

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

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, чтобы новое имя не удалось сохранить.)

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

2
ответ дан user1612868 23 August 2018 в 15:39
поделиться

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

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

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

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

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

2
ответ дан user5553647 23 August 2018 в 15:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: