Зачем используется базовая ячейка с расширением строки в iOS
Что проверяют
Формулировка размытая, поэтому сначала уточните, о чём речь. Чаще всего имеют в виду связку базового класса ячейки и расширения, которое берёт строковый reuse identifier из имени класса. Проверяют, понимаете ли вы, как работает переиспользование ячеек и зачем прятать строковые идентификаторы.
Как отвечать
UITableView не создаёт ячейку на каждую строку, а берёт её из очереди переиспользования по строковому идентификатору. Руками это выглядит как dequeueReusableCell(withIdentifier: "CustomCell", for:) и as!. Опечатка в строке или забытая регистрация всплывает только крэшем в рантайме.
Поэтому делают две вещи:
- расширение:
extension UITableViewCell { static var reuseIdentifier: String { String(describing: self) } }. Идентификатор равен имени класса, строк в коде больше нет. К нему добавляют дженерик-методыregister(_:)иdequeue(_:for:)в расширенииUITableView, и каст живёт в одном месте; - базовая ячейка:
BaseTableViewCellс общим поведением:selectionStyle, отступы, шаблонныеsetupViews()иsetupConstraints(), сброс состояния вprepareForReuse(). Наследники переопределяют только своё.
Добавьте современный вариант. С iOS 14 есть UICollectionView.CellRegistration и dequeueConfiguredReusableCell(using:for:item:): строковых идентификаторов нет вовсе, конфигурация типизирована. Для списков есть UICollectionLayoutListConfiguration, а с iOS 16 UIHostingConfiguration позволяет описать содержимое ячейки на SwiftUI.
Если под «расширением строки» имели в виду раскрывающуюся ячейку, ответ другой: самосайзинг через Auto Layout и UITableView.automaticDimension, смена констрейнтов и анимированное обновление высоты через performBatchUpdates.
Где спотыкаются
Путают переиспользование ячеек с переиспользованием кода. Очередь dequeue экономит память и время на создание, базовый класс экономит код.
Не сбрасывают состояние в prepareForReuse. Картинка, загруженная асинхронно для прошлой строки, появляется в новой.
Раздувают базовый класс до десятка флагов и уровней наследования. Общее поведение часто проще вынести в протокол с расширением, чем тянуть иерархию.