Какой метод UITableView используется для dequeue ячейки
Что проверяют
Название метода знают почти все. Проверяют, понимаете ли вы механизм переиспользования: откуда берутся ячейки, чем отличаются две версии метода и что нужно сбросить перед повторным показом. Следом обычно спрашивают про prepareForReuse и про картинки, которые появляются не в той ячейке.
Как отвечать
Основной метод dequeueReusableCell(withIdentifier:for:). Его вызывают в tableView(_:cellForRowAt:), и он всегда возвращает ячейку: берёт свободную из очереди переиспользования или создаёт новую по зарегистрированному классу. Если идентификатор не зарегистрирован, приложение падает с NSInternalInconsistencyException, и это полезно: ошибка видна сразу.
Дальше покажите, что знаете окружение метода:
- регистрация:
register(_:forCellReuseIdentifier:)с классом илиUINib, либо прототип ячейки в сториборде; - старая версия:
dequeueReusableCell(withIdentifier:)безindexPathвозвращает опционал и отдаётnil, если свободной ячейки нет и ничего не зарегистрировано. В новом коде берут версию сfor:; - пул: ячеек создаётся примерно столько, сколько помещается на экране, плюс запас. Ушедшая за край ячейка возвращается в очередь и приходит уже для другой строки;
prepareForReuse(): переопределяется в подклассе ячейки, чтобы сбросить состояние: отменить загрузку картинки, снять выделение, вернуть скрытые элементы;- конфигурация: с iOS 14 рекомендуемый путь это
defaultContentConfiguration()иcontentConfigurationвместоtextLabelиdetailTextLabel.
С UITableViewDiffableDataSource метод тот же, его вызывают в замыкании, которое создаёт ячейки.
Где спотыкаются
Не сбрасывают состояние. Ячейка с галочкой или скрытой кнопкой приходит для другой строки в том же виде, и в списке появляются «призраки».
Асинхронно грузят картинку и ставят её в ячейку по завершении запроса. Пока шла загрузка, ячейку переиспользовали, и фото оказывается не у той строки. Отменяйте задачу в prepareForReuse или сверяйте идентификатор модели перед установкой.
Смешивают две версии: регистрируют класс, но вызывают старый метод и пишут ветку if cell == nil, которая никогда не выполнится.