我正在开发一个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服务器请求并返回所有结果,即使应用程序的视图仅需要最多三个请求的结果。这偶尔会导致图片显示在错误的行中,或显示延迟。
如果用户滚动得太快,如何阻止/取消我的服务器请求。或者有更好的方法来实现它以获得所需的效果吗?
答案 0 :(得分:4)
这偶尔会导致图片显示在错误的行中
在解决问题的其他部分之前,您应该尝试理解为什么会发生这种情况。
根据我的经验,(当然取决于图像的大小),最好从服务器获取图像而不是取消它。虽然你应该记住一些事情:
一旦你拥有它就缓存它,并确保在要求新的之前检查你的缓存。您可以使用NSDictionary
,密钥是图片的网址。
异步调用。您不应该使用请求/缓存部分阻止/强调您的UI线程。使用NSOperations
和NSOperationQueue
创建小型工作人员来处理请求和缓存。获得后,只需更新UIImageView
。
在获取图片时保留占位符。这向用户显示正在发生的事情。
更新您的数据源,而不是您的单元格。原因是,如果你看到行[0,1,2,3,4,5]并滚动,现在你看到行[40,41,42,43,44,45],当回复时附带第一行的图像,细胞已经消失了(可能是您在错误的地方遇到图像时遇到的问题)。
最后,因为你提到Pulse News,为什么不跟他们学习一下呢?使用this链接访问其工程页面,并了解有关下载图像的信息。 :)
答案 1 :(得分:0)
答案 2 :(得分:-1)
你不应该在每个cellForRowAtIndexPath:上创建照片请求。你应该使用异步图像缓存lib,它们很少:我使用JMImageCache。