ios - 当用户滚动太快时如何停止服务器调用?

标签 ios asynchronous uitableview scroll

我正在开发一个 iPhone 应用程序,它从服务器检索照片并将它们显示在屏幕上,类似于 Pulse News Reader 显示其文章的方式。我有一个垂直滚动的 UITableView,每个 UITableViewCell 都包含自己的自定义 UITableView 实例,允许用户水平浏览照片。

我目前填充水平滚动表的方式是在垂直滚动表的 cellForRowAtIndexPath 方法中进行服务器调用。每当一个新的单元格进入 View 时,我都会发送一个请求,获取该特定单元格的照片,如下面的代码所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"EventCell";

    EventViewCell *cell = (EventViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[EventViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    Event *event = [self.fetchedResultsController objectAtIndexPath:indexPath];

    [self performPhotoFetchForEventID:event.id inCell:cell withRetries:3];

    return cell;
}

当用户缓慢滚动垂直表格时,此解决方案非常有效,但如果用户快速滚动或“轻拂”列表,它就会开始崩溃。本质上,如果用户真的快速滚动浏览 X 个事件,应用程序将触发 X 个服务器请求并返回所有结果,即使应用程序的 View 最多只需要其中三个请求的结果。这偶尔会导致图片显示在错误的行中,或者显示延迟。

如果用户滚动得太快,我如何防止/取消触发我的服务器请求。或者有没有更好的方法来实现它以获得预期的效果?

最佳答案

This occasionally causes pictures to show up in the wrong rows

在解决问题的其他部分之前,您应该尝试了解发生这种情况的原因。

根据我的经验,(当然取决于图像的大小),最好只从服务器获取图像而不是取消它。虽然你应该记住一些事情:

  • 一旦拥有它就缓存它,并确保在请求新的之前检查您的缓存。您可以使用 NSDictionary,键是图像的 URL。

  • 异步调用。您不应该使用 Request/Cache 部分阻塞/强调您的 UI 线程。使用 NSOperationsNSOperationQueue 创建小型 worker 来处理请求和缓存。一旦你得到它,只需更新你的 UIImageView

  • 在获取图像时留下一个占位符。这向用户表明正在发生某些事情。

  • 更新您的数据源而不是您的单元格。原因是,如果您看到行 [0,1,2,3,4,5] 并且滚动,现在您看到行 [40,41,42,43,44,45],当响应第一行带有图像,单元格早已消失(可能是您在错误位置遇到图像的问题)。

  • 最后,因为您提到 Pulse News,为什么不向他们学习一下呢?使用 this链接访问他们的工程页面并学习一些关于下载图像的知识。 :)

关于ios - 当用户滚动太快时如何停止服务器调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13394395/

相关文章:

ios - 如何根据uitextfield的标签id获取uitextfield中的值?

ios - uitableviewcells 中的重复内容

ios - 向下滚动并从 UITableViewController 返回时,导航栏标题变小

c++ - 从 C++ 运行 CURL 以异步获取多个 URL

ios - `UITableView` 顶部的额外空间

swift - 两个部分和不同的三个单元

ios - collectionView 中的内容大小错误

ios - Cordova 2.3.0 在 iOS 上的 Safari 中打开链接

javascript - 在 React 组件中等待异步函数并显示 Spinner

c# - 我需要为每个方法使用单独的线程锁吗?