Что такое проблема слайд-шоу (фликер) при скроллинге в UITableView/UICollectionView и как её решить?

«Что такое проблема слайд-шоу (фликер) при скроллинге в UITableView/UICollectionView и как её решить?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Проблема слайд-шоу (фликера) — это визуальный артефакт, когда изображения в переиспользуемых ячейках подгружаются асинхронно и появляются в неправильном порядке при быстром скроллинге.

Причина:

  1. Переиспользование ячеек: Ячейка с indexPath A начинает загрузку изображения, но переиспользуется для indexPath B до завершения запроса.
  2. Отсутствие отмены: Старый асинхронный запрос завершается и устанавливает изображение в уже переиспользованную ячейку, «перезаписывая» контент для нового indexPath.

Решение — проверка актуальности: Перед установкой изображения нужно убедиться, что ячейка всё ещё отображает тот же контент.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    // 1. Устанавливаем уникальный идентификатор для текущей конфигурации ячейки
    let currentTag = indexPath.row
    cell.tag = currentTag

    // 2. Запускаем асинхронную загрузку
    loadImage(for: indexPath) { [weak cell] image in
        DispatchQueue.main.async {
            // 3. Устанавливаем изображение, только если тег ячейки совпадает
            if cell?.tag == currentTag {
                cell?.imageView?.image = image
            }
        }
    }
    return cell
}

Дополнительные меры:

  • В prepareForReuse() ячейки следует отменять старые запросы на загрузку.
  • Использовать специализированные библиотеки (например, SDWebImage или Kingfisher), которые инкапсулируют эту логику и кэширование.