Документы для NSFetchedResultsControllerDelegate предоставляют следующий пример кода
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
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 reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
Когда я создаю новый объект NSManagedObject, срабатывает NSFetchedResultsChangeInsert (отлично!). Когда я изменяю значение атрибута (используется для заголовка ячейки), срабатывает NSFetchedResultsChangeUpdate. К сожалению, новый заголовок не отображается автоматически, если я не перезаряжу таблицу, раздел или строку. Действительно, если новое имя заставляет результирующий набор сортироваться по-разному, то срабатывает NSFetchedResultsChangeMove, и все хорошо, так как предоставленный код перезагружает весь раздел.
UITableView имеет метод reloadRowsAtIndexPaths: withRowAnimation, поэтому я попытался использовать его в блоке NSFetchedResultsChangeUpdate. Это действительно работает... но документы для этого конкретного метода читаются так, как будто мне это не нужно (обратите внимание на последнюю строку):
Перезагрузка строки вызывает для просмотра своего источника данных для новая ячейка для этой строки. Стол оживляет, что новая ячейка в ней оживляет старую строку. Назовите это метод, если вы хотите предупредить пользователя что значение ячейки меняется. Если, однако, уведомление пользователя не важно, то есть вы просто хотите измените значение, которое ячейка отображение - вы можете получить ячейку для определенную строку и установите ее новое значение.
И да, если я регистрирую, что происходит, когда
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
вызывается на NSFetchedResultsChangeUpdate, он может получить последнее значение "name" и установить его в ячейке textLabel. Это имя просто не отображается в ячейке, если я не перезагружу его. Даже если я просто щелкнул по ячейке, появится имя. Обратите внимание, что для воссоздания этого поведения вы должны создать новый управляемый объект, а затем дать ему имя, которое заставляет его сортировать FIRST в NSFetchedResultsController. Таким образом, NSFetchedResultsChangeMove не срабатывает (что работает, так как он перезагружает раздел).
Я что-то упустил или это ожидаемое поведение? "Обсуждение" для reloadRowsAtIndexPaths приводит меня к мысли, что я должен просто установить ячейку textLabel без перезагрузки строки, раздела или таблицы.