UITableView与有限的滚动和延迟加载

我得到了一个UITableView充满了未知数量的行。 每行包含(例如3个)图像,应用程序从web服务收集这些信息。

对于UITableView我实现了无限滚动。 每当表几乎到达当前的行数的末尾,我发起一个调用web服务,以获取接下来的50行数据。 我在由UITableView调用的scrollViewDidScroll方法中执行此操作。

 - (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在其文档中build议的相同。 该图像也添加到本地NSDictionary ,所以我可以获取它时,行滚动出来的屏幕,并返回(和行重新创build)。

由于单个视图中的图片数量可能会高达2000 – 3000,因此我还将图像caching到磁盘,并在远离X行的位置清除NSDictionary的图像。 当用户再次向下滚动时,会发生以下情况:

  1. 显示新行
  2. 将调用延迟加载方法,该方法检查映像是存在于磁盘上还是应该下载。
  3. 从磁盘下载或取出图像时,会执行一个代码块,在该行中显示图像。 从互联网下载的图像也被caching到磁盘。
  4. UIImage被添加到NSDictionary以便更快速地caching需要触及的图像。
  5. 由于内存问题( NSDictionary太多的UIImage对象会导致内存不足错误),将从NSDictionary中删除行中15行或远离可见行的图像。

当UITableView几乎达到最后,会发生以下情况:

  1. UITableView几乎到达当前加载行的末尾
  2. 调用webservice,加载新行(50)
  3. 新行添加到数组中,用于numberOfItemsInSection方法。
  4. 调用reloadData以确保UITableView填充额外的新行。
  5. 包含图像的新行执行上述步骤以延迟加载图像。

所以,我的问题是当我从web服务添加新的logging。 当我在UITableView上调用reloadData ,一些图像再次从磁盘加载,一些滚动的时候发生了一些混乱。

我正在寻找一个解决scheme。 我尝试使用insertItemsAtIndexPaths与新行的数量,将它们添加到UITableView ,但这使得我的懒加载方法已经下载图像(因为不知何故所有单元格是在那个时候创build​​的,即使它们不可见,检查是否单元格在创build过程中是可见的,提供了意想不到的结果,图像没有加载,单元格看起来很古怪等)

所以,我基本上寻找的是一个无限的滚动UITableView的解决scheme,懒惰从networking/磁盘加载图像,并像照片应用程序一样顺利。 由于图像全部加载在不同的线程,我不明白为什么滚动不如婴儿的皮肤光滑。

我不确定我是否完全赞同你的问题,但是当遇到类似的问题时,我做了一些事情。

  • 我用-tableView:cellForRowAtIndexPath:作为我的线索从networking加载更多的数据。 我选了一个数字(在我的情况下是10),当indexPath.row + 10 >= self.data.count加载更多的数据。

    • 我需要调用-tableView:cellForRowAtIndexPath:无论如何。
    • 我没有强制callback-scrollViewDidScroll:更紧密的循环。
  • 我将UIImageView为一个类,它将asynchronous加载我称为URLImageView图像。

    • -tableView:cellForRowAtIndexPath: ,我为URLImageView实例分配了一个URL。
    • 该分配导致后台操作,将从磁盘加载或从networking加载。
    • 该操作是可取消的,所以我没有继续工作,不再需要加载的图像。

我有一个表视图与数百(但不是数千)的图像。 我一次只有2或3个表格单元。

  • 我使用了-refreshData :它像冠军一样工作。
  • 我甚至有URLImageView淡入图像。 这是一个非常好的效果。

我希望有帮助。

为了避免闪烁,请尝试调用beginUpdates上的beginUpdates ,然后insertrowAtIndexPaths:withRowAnimations:并使用endUpdates完成。

祝你好运。