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

时间:2012-11-15 09:15:02

标签: ios asynchronous uitableview scroll

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

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

- (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服务器请求并返回所有结果,即使应用程序的视图仅需要最多三个请求的结果。这偶尔会导致图片显示在错误的行中,或显示延迟。

如果用户滚动得太快,如何阻止/取消我的服务器请求。或者有更好的方法来实现它以获得所需的效果吗?

3 个答案:

答案 0 :(得分:4)

  

这偶尔会导致图片显示在错误的行中

在解决问题的其他部分之前,您应该尝试理解为什么会发生这种情况。

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

  • 一旦你拥有它就缓存它,并确保在要求新的之前检查你的缓存。您可以使用NSDictionary,密钥是图片的网址。

  • 异步调用。您不应该使用请求/缓存部分阻止/强调您的UI线程。使用NSOperationsNSOperationQueue创建小型工作人员来处理请求和缓存。获得后,只需更新UIImageView

  • 在获取图片时保留占位符。这向用户显示正在发生的事情。

  • 更新您的数据源,而不是您的单元格。原因是,如果你看到行[0,1,2,3,4,5]并滚动,现在你看到行[40,41,42,43,44,45],当回复时附带第一行的图像,细胞已经消失了(可能是您在错误的地方遇到图像时遇到的问题)。

  • 最后,因为你提到Pulse News,为什么不跟他们学习一下呢?使用this链接访问其工程页面,并了解有关下载图像的信息。 :)

答案 1 :(得分:0)

如果您使用NSUrlConnection以延迟加载模式检索图像,则可以将此命令发送到连接:

[connection cancel];

Here the Apple docs

答案 2 :(得分:-1)

你不应该在每个cellForRowAtIndexPath:上创建照片请求。你应该使用异步图像缓存lib,它们很少:我使用JMImageCache。