Как удалить строку таблицы в контроллере разделенного представления

Я пытаюсь удалить строку таблицы, которая отображается в моем контроллере разделенного представления. Когда я смахиваю влево и нажимаю «Удалить», мое приложение вылетает, и я получаю сообщение об ошибке:

Завершение приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «Недопустимое обновление: недопустимое количество строк в разделе 0. Количество строк, содержащихся в существующем разделе после обновления (44), должно быть равно количеству строк, содержащихся в этом раздел до обновления (44), плюс или минус количество строк, вставленных или удаленных из этого раздела (0 вставленных, 1 удаленных) и плюс или минус количество строк, перемещенных в этот раздел или из него (0 перемещенных, 0 перемещенных вне).'

Мне удалось заставить параметр перераспределения работать для табличного представления без каких-либо ошибок. Для функции удаления строки я сделал следующее:

- (void)tableView:(UITableView *)tableView commitEditingStyle:  (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [_objects removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
    withRowAnimation:UITableViewRowAnimationAutomatic];   
}

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

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

https://github.com/mithunan/presidents-splitView

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

РЕДАКТИРОВАТЬ----

Это метод numberOfRowsInSection:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.presidents count];
}

и этот метод тоже может помочь...

// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
    id object = [self.presidents objectAtIndex:fromIndexPath.row];
    [_objects removeObjectAtIndex:fromIndexPath.row];
    [_objects insertObject:object atIndex:toIndexPath.row];
}

Спасибо

РЕДАКТИРОВАТЬ 2 -------------

Основываясь на информации, предоставленной rmaddy, я изменил commitEditingStyle...

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.presidents removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

}

Но теперь я получаю ошибку сборки: никакой видимый @interface для NSArray объявляет селектор «removeObjectAtIndex:»

Извините, если я прошу слишком многого, но не могли бы вы рассказать мне об этом.


person MythRaven    schedule 04.08.2014    source источник
comment
На какой версии iOS вы тестируете?   -  person rmaddy    schedule 04.08.2014
comment
Я тестировал свою версию 7.0 на реальном устройстве и версию 7.1 на симуляторе на xcode 5. Примечание. Я создал приложение в бета-версии xcode6 2. Но у меня была цель для ios 7.0.   -  person MythRaven    schedule 04.08.2014
comment
В iOS 8 есть ошибки, но в iOS 7 должно работать. Две вещи: 1) Убедитесь, что _objects не является nil при вызове commitEditingStyle. 2) Убедитесь, что ваш numberOfRowsInSection возвращает правильное новое количество строк после удаления объекта из _objects.   -  person rmaddy    schedule 04.08.2014
comment
я добавил точку останова внутри метода commitEditingStyle, в строке deleteRowsAtIndexPaths, и в нижнем окне отладки он говорит, что _objects равен нулю. Я относительно новичок в этом, и я не уверен, что мне делать дальше.   -  person MythRaven    schedule 04.08.2014
comment
Тогда в этом проблема. Поскольку _objects равно nil, вы не обновляете свою модель данных, чтобы отразить удаленную строку. Опубликуйте свой метод numberOfRowsInSection в своем вопросе. Что он использует для возврата количества строк? Это _objects или что-то другое?   -  person rmaddy    schedule 04.08.2014
comment
я использовал return [self.presidents count];... я отредактировал исходный пост, см. выше. Должен ли я сделать что-то вроде выше?   -  person MythRaven    schedule 04.08.2014
comment
Ну вот. Ваш источник данных основан на self.presidents, но по какой-то неизвестной причине вы пытаетесь обновить _objects. Это бессмысленно. Вам нужно использовать одни и те же данные. Удалите объект из self.presidents вместо _objects. То же и с ходом.   -  person rmaddy    schedule 04.08.2014
comment
@rmaddy Я не думаю, что понимаю это так, как должен. Я попробовал то, что вы сказали, но получил другую ошибку, ошибку сборки. Пожалуйста, смотрите Edit 2 в моем исходном вопросе. Кроме того, я прикрепил проект к центру GIT... github.com/mithunan/presidents-splitView Не могли бы вы дать мне более подробную информацию о том, как я могу решить эту проблему. Ряды переставляются. P.S., мои данные поступают из plist. Большое спасибо.   -  person MythRaven    schedule 05.08.2014
comment
Вам нужно сделать свой presidentsArray изменяемым.   -  person rmaddy    schedule 05.08.2014


Ответы (1)


Всегда полезно добавлять вызовы методов beginUpdates и endUpdates всякий раз, когда вы меняете модель табличного представления:

- (void)tableView:(UITableView *)tableView commitEditingStyle:  (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView beginUpdates];
    [_objects removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
}

Из документации метода beginUpdates:

Начните серию вызовов методов, которые вставляют, удаляют или выбирают строки и разделы приемника. Вызовите этот метод, если вы хотите, чтобы последующие операции вставки, удаления и выбора (например, cellForRowAtIndexPath: и indexPathsForVisibleRows) анимировались одновременно. Эта группа методов должна завершаться вызовом endUpdates. Эти пары методов могут быть вложенными. Если вы не выполняете вызовы вставки, удаления и выбора внутри этого блока, атрибуты таблицы, такие как количество строк, могут стать недействительными. Вы не должны вызывать reloadData внутри группы; если вы вызываете этот метод внутри группы, вам нужно будет выполнять любые анимации самостоятельно.

person Rinat Khanov    schedule 04.08.2014
comment
Использование begin/endUpdates не должно быть необходимым при выполнении только одного вызова для удаления, вставки или перезагрузки строк. - person rmaddy; 04.08.2014
comment
@rmaddy Я не говорю, что это необходимо во всех случаях, но, исходя из моего опыта, это может исправить некоторое странное поведение, когда одновременно происходит несколько вызовов для обновления представления таблицы. - person Rinat Khanov; 04.08.2014
comment
Но это не тот случай. Это простое удаление с помощью одного вызова deleteRows. И похоже, что источник данных правильно обновляется по мере необходимости. Использование begin/endUpdates не требуется. Теперь, сказав все это, кажется, что в iOS 8 есть куча ошибок табличного представления. Я столкнулся с несколькими. Ваш ответ действительно работает с ошибкой iOS 8, но в этом нет необходимости. - person rmaddy; 04.08.2014
comment
Я попытался добавить ваше предложение, но все равно получаю ту же ошибку. - person MythRaven; 04.08.2014
comment
@rmaddy Да, мне тоже приходилось иметь дело с UITableView ошибками в iOS 8, и этот обходной путь мне помог. Вызов этих методов не повредит, если это решит проблему, верно? - person Rinat Khanov; 04.08.2014
comment
@RinatKhanov вам нужно создать простое тестовое приложение, которое демонстрирует ошибку, и отправить отчет об ошибке в Apple. Таким образом, они могут решить проблему, поэтому всем не придется добавлять хаки в свой код. Не помешает добавить вызовы begin/endUpdate, чтобы исправить это в одном месте. Это больно, когда вам приходится возвращаться и изменять десятки классов, которые работали с iOS 3.0 из-за ошибки в iOS 8. :) - person rmaddy; 04.08.2014