UITableView с бесконечной прокруткой и отложенной загрузкой

Я получил UITableView, который заполнен неизвестным количеством строк. Каждая строка содержит (, например 3 )изображений, и приложение получает эту информацию от веб-службы.

Для UITableViewя реализовал бесконечную прокрутку. Всякий раз, когда таблица почти достигает конца текущего количества строк, я инициирую вызов веб-службы, чтобы получить следующие 50 строк данных. Я делаю это в методе scrollViewDidScroll, который вызывается методом UITableView.

- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat actualPosition = scrollView.contentOffset.y;

    float bottomOffset = 450;
    if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        bottomOffset = 1000;

    CGFloat contentHeight = scrollView.contentSize.height - bottomOffset;
    if (actualPosition >= contentHeight && !_loading && !_cantLoadMore)
    {
        self.loading = YES;

        _currentPage++;

        NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
        [dict setObject:[NSNumber numberWithInt:_currentPage] forKey:@"page"];
        [dict setObject:[_category objectForKey:@"ID"] forKey:@"category"];

        [self performSelectorInBackground:@selector(getWallpapersInBackground:) withObject:dict];
    }
}

Изображения в строках UITableViewзагружаются лениво. Всякий раз, когда строка видна, изображения загружаются в отдельный поток, а строки обновляются после полной загрузки изображения. Принцип, который я использую для ленивой загрузки, такой же, как Apple предлагает в своей документации. Изображение также добавляется в локальный NSDictionary, поэтому я могу получить его, когда строка прокручивается за пределы экрана и обратно в (, и строка воссоздается ).

Поскольку количество изображений в одном представлении может достигать 2000 -3000, я также кэширую изображения на диск и удаляю изображения из NSDictionary, когда они находятся дальше X строк. Когда пользователь прокручивает вниз и снова вверх, происходит следующее:

  1. Отображаются новые строки
  2. Вызывается метод ленивой загрузки, который проверяет, присутствует ли образ на диске или должен ли он его загрузить.
  3. Когда изображение загружается или извлекается с диска, выполняется кодовый блок, который отображает изображение в строке. Изображения, загруженные из Интернета, также кэшируются на диск.
  4. UIImageдобавлен к NSDictionaryдля более быстрого кэширования изображений, которые должны быть в пределах досягаемости.
  5. Изображения, находящиеся в строках, на 15 строк или дальше от видимых строк, удаляются из NSDictionaryиз-за проблем с памятью (слишком много UIImageобъектов в NSDictionaryпричиной -нехватки -памяти ошибки ).

Когда UITableView почти достигает конца, происходит следующее:

  1. UITableView почти достигает конца загруженных в данный момент строк
  2. Вызов веб-сервиса с множеством новых строк (50)
  3. Новые строки добавляются в массив, который используется для метода numberOfItemsInSection.
  4. reloadDataвызывается, чтобы убедиться, что UITableViewзаполнен дополнительными новыми строками.
  5. Новые строки, содержащие изображения, выполняют шаги, упомянутые выше, для ленивой загрузки изображений.

Итак, у меня проблема, когда я добавляю новые записи из веб-сервиса. Когда я вызываю reloadDataна UITableView, некоторые изображения снова загружаются с диска, и при прокрутке возникают некоторые зависания.

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

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

11
задан Wim Haanstra 30 June 2012 в 12:02
поделиться