Trochę utknąłem z tym ... każda pomoc jest bardzo doceniana. Sporo już czasu poświęciłem na debugowanie tego.UITableViewCell słaba wydajność z AutoLayout
Mam UITableView
ze źródłem danych dostarczonym przez NSFetchedResultsController
. W oddzielnym kontrolerze widoku wstawiam nowe rekordy do CoreData przy użyciu [NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
, zapisz kontekst obiektu zarządzanego i odrzuć ten kontroler. Bardzo standardowe rzeczy.
Zmiany w kontekście zarządzanego obiektu są następnie odbierane przez 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;
}
}
I tu pojawia się problem - to trwa zbyt długo (około 3-4 sekund na iPhone 4), aby to zrobić. Wydaje się, że czas poświęcony jest na obliczanie układu komórek.
Usunąłem wszystko z komórki (w tym niestandardową podklasę) i zostawiłem tylko z UILabel
, ale nic się nie zmieniło. Potem zmieniłem styl komórki na Basic (lub cokolwiek oprócz Custom), a problem zniknął - nowe komórki są dodawane natychmiastowo.
Podwajałem się, sprawdzając i wywołania zwrotne NSFetchedResultsControllerDelegate
są wywoływane tylko raz. Jeśli je zignoruje i zrobię [UITableView reloadSections:withRowAnimation:]
nic się nie zmieni - nadal jest bardzo powolny.
Wygląda na to, że automatyczne układanie jest wyłączone dla domyślnych stylów komórek, co czyni je bardzo szybkimi. Ale jeśli tak jest - dlaczego wszystko ładuje się szybko, gdy naciskam na UITableViewController
?
Oto ślad wezwanie do tego problemu:
Więc pytanie jest - co tu się dzieje? Dlaczego komórki są renderowane tak wolno?
UPDATE 1
I został zbudowany bardzo prostą aplikację demo, który ilustruje problem mam. tutaj źródło - https://github.com/antstorm/UITableViewCellPerformanceProblem
Spróbuj dodać co najmniej ekran komórek, aby poczuć problemy z wydajnością.
Należy również pamiętać, że bezpośrednie dodanie wiersza (przycisk "Wstaw teraz!") Nie powoduje spowolnienia.
Wystarczy, że potwierdzisz - Czy przypisujesz komórkom niestandardowym unikalny identyfikator i piszecie je zamiast ponownie tworzyć, prawda? – James
i jakie reguły automatycznego układu są określone w komórce? – Wain
Tak, przypisuję unikalny identyfikator i piszę komórki za pomocą '[UITableView dequeueReusableCellWithIdentifier: forIndexPath:]'. –