Добейтесь плавной прокрутки для Photo Grid с тысячами изображений с диска

У меня есть PhotoGrid с тремя фотографиями в каждом ряду, реализованные с использованием UITableView,

У меня есть кэш в памяти (использующий NSCache), который вмещает 100 изображений, поэтому в один момент у меня будет не более 100 изображений в памяти, даже если у меня есть тысячи изображений на диске для отображения в Grid.

Все мои изображения 4KB-20KB JPEG.

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

Когда пользователь начинает прокручивать быстрее вперед и назад, у меня есть два случая:

  1. Если я отделю задачу загрузки изображений от основного потока, я получаю отсутствующие изображения в сетке фотографий, потому что мои ячейки отображаются до того, как изображения будут считаны в память.

    (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            UIImage *image = getImageFromCacheForImagePath:imagePath;
            dispatch_async(dispatch_get_main_queue(), ^{
                cell.leftGridItem.imageView.image =  image;
            });
        });
    }
    
  2. Если у меня есть задача загрузки изображений в главном потоке, возникает заикание. Я получаю около 36-45 кадров в секунду.

    (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UIImage *image = getImageFromCacheForImagePath:imagePath;
        cell.leftGridItem.imageView.image = image;
    }
    

getImageFromCacheForImagePath:imagePath получает изображение сразу из NSCache, если оно существовало, если нет, изображение загружается из файла и устанавливается в NSCache для последующего использования, но я установил предел NSCache до 100.

Вещи, которые я пробовал / подправил:

  1. избежать clipsToBounds для просмотра изображений сетки.
  2. Загрузка изображений в фоновом потоке.
  3. Использование NSOperation Очереди.
  4. Загрузка изображений партиями по 100 (работает, но с быстрой прокруткой, время загрузки изображения было отложено).

Я пытаюсь добиться того же ощущения, что и родное приложение Photos.

Ваши предложения приветствуются.

2 ответа

Я реализовал таблицу плавной прокрутки с более чем 700 изображениями. Ключом было не только загрузить изображения в фоновом режиме, но и изменить его размер в фоновом режиме, чтобы он идеально подходил для контейнера. Изменение размера - слишком сложная операция, чтобы сделать это в потоке пользовательского интерфейса.

Я также столкнулся с той же проблемой несколько дней назад, поэтому GitHub - лучшее место для поиска решений с открытым исходным кодом, поэтому попробуйте эти ссылки.

Проверьте PF-GridView или DTGridView.

также взгляните на AQGridView, Как написать пользовательский инструмент выбора изображений, такой как UIImagePicker,

Просто нужно сделать немного манипуляции в соответствии с нашими потребностями, и это работает как чемпион.

Другие вопросы по тегам