Я немного застрял с этим... любая помощь очень ценится. Я уже много времени отлаживал это.
У меня есть UITableView
с источником данных, предоставленным NSFetchedResultsController
. В отдельном контроллере просмотра я вставляю новые записи в CoreData с помощью [NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
, сохраняю контекст управляемого объекта и увольняю его. Очень стандартный материал.
Изменения в контексте управляемого объекта затем принимаются NSFetchedResultsController
:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
}
}
И здесь возникает проблема - для этого требуется слишком много времени (примерно 3-4 секунды на iPhone 4). И кажется, что время потрачено на расчет макета для ячеек.
Я удалил все из ячейки (включая пользовательский подкласс) и оставил ее только с UILabel
, но ничего не изменилось. Затем я изменил стиль ячейки на Basic (или ничего, кроме Custom), и проблема исчезла - новые ячейки добавляются мгновенно.
Я дважды проверял и NSFetchedResultsControllerDelegate
обратные вызовы вызываются только один раз. Если я игнорирую их и делаю [UITableView reloadSections:withRowAnimation:]
, ничего не меняется - он все еще очень медленный.
Мне кажется, что Auto Layout отключен для стилей ячейки по умолчанию, что делает их очень быстрыми. Но если это так - почему все быстро загружается, когда я нажимаю UITableViewController
?
Здесь трассировка вызова для этой проблемы:
Итак, вопрос в том, что здесь происходит? Почему клетки отображаются так медленно?
ОБНОВЛЕНИЕ 1
Я создал очень простое демонстрационное приложение, которое иллюстрирует проблему, с которой я сталкиваюсь. здесь источник - https://github.com/antstorm/UITableViewCellPerformanceProblem
Попробуйте добавить, по крайней мере, экранные ячейки, чтобы почувствовать проблемы с производительностью.
Также обратите внимание, что добавление строки непосредственно (кнопка "Вставить сейчас!" ) не вызывает какой-либо медлительности.