"didChangeSection:" NSfetchedResultsController метод делегата не вызывается - PullRequest
5 голосов
/ 09 января 2011

У меня есть стандартный контроллер разделенного представления с подробным представлением и табличным представлением.Нажатие кнопки в подробном представлении может привести к тому, что объект изменит свое расположение в порядке табличного представления.Это работает нормально, если результирующее изменение порядка не приводит к добавлению или удалению раздела.Т.е. объект может изменить свой порядок в разделе или переключиться с одного раздела на другой.Изменения в заказе работают корректно, без проблем.Но если объект пытается перейти к разделу, который еще не существует, или является последним объектом, покинувшим раздел (следовательно, требующий удаления раздела, по которому он покидает раздел), то происходит сбой приложения.

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

Код, о котором идет речь, является стандартным:

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

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSLog(@"didChangeSection");

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {    
NSLog(@"didChangeObject");

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"didChangeContent");
    [self.tableView endUpdates];

    [detailViewController.reminderView update];
}

Запуск приложения и последующий вывод последнего объекта из раздела.приводит к следующему выводу:

2011-01-08 23:40:18.910 Reminders[54647:207] willChangeContent
2011-01-08 23:40:18.912 Reminders[54647:207] didChangeObject
2011-01-08 23:40:18.914 Reminders[54647:207] didChangeContent
2011-01-08 23:40:18.915 Reminders[54647:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1145.66/UITableView.m:825
2011-01-08 23:40:18.917 Reminders[54647:207] Serious application error.  Exception was caught during Core Data change processing: Invalid update: invalid number of sections.  The number of sections contained in the table view after the update (5) must be equal to the number of sections contained in the table view before the update (6), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)

Как вы видите, "willChangeContent", "didChangeObject" (перемещение рассматриваемого объекта) и "didChangeContent" были вызваны правильно.Основываясь на документации NSFetchedResultsControllerDelegate от Apple, "didChangeSection" должен был быть вызван до "didChangeObject", что предотвратило бы исключение, вызывающее сбой.

Так что я думаю, вопрос в том, как я могу убедиться, что didChangeSection вызывается?1013 *

Заранее спасибо за любую помощь!

Ответы [ 2 ]

1 голос
/ 12 января 2011

Я делаю то же самое в своем приложении (временное свойство в sectionNameKeyPath) и не вижу проблемы, с которой вы столкнулись.Я тестирую это на iOS 4.2.1 ... Существует известная ошибка, из-за которой вы не можете доверять любым обратным вызовам делегатов FRC в iOS 3.X, вы должны сделать полное [tableView reloadData] в сообщении controllerDidChangeContent:. см. Документацию FRC

Я протестировал переход от существующего раздела с другой записью к несуществующему разделу, а также от раздела с одной строкой к другому несуществующему разделу.

1 голос
/ 10 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...