UITableView屏幕上的图像下载延迟加载

首先这不是重复的。 我看到了一些相同的问题,但他们没有帮助我,因为我的问题有一点变化。

使用下面的代码我在我的项目中asynchronous下载图像。

{ NSURL *imageURL = [NSURL URLWithString:imageURLString]; [self downloadThumbnails:imageURL]; } - (void) downloadThumbnails:(NSURL *)finalUrl { dispatch_group_async(((RSSChannel *)self.parentParserDelegate).imageDownloadGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *tempData = [NSData dataWithContentsOfURL:finalUrl]; dispatch_async(dispatch_get_main_queue(), ^{ thumbnail = [UIImage imageWithData:tempData]; }); }); } 

由于程序的逻辑,我已经使用了上述代码,而不是tableview控制器,它显示所有的数据后,从Web服务获取它的文件。

问题:在屏幕上图像不显示,直到我滚动。 屏幕图像首先被刷新。 我能做些什么来解决我的问题。

苹果的延迟加载项目是使用scrollViewDidEndDragging和scrollViewDidEndDecelerating加载图像,但项目是太大了无法理解,加上我的代码是在除了tableview控制器以外的文件。

注意:请不要推荐像SDWebImage等第三方库

更新:由于大多数人无法得到的问题,我必须澄清,这个问题是不是与下载,caching和重新加载tableview中的图像相关联。 所以请不要推荐第三方库。 问题是图像只显示在用户滚动tableview,而不是加载屏幕上的。

提前致谢

我认为你必须做的是:

  1. 当图像被下载时,在表格单元格中显示一些占位符图像(否则你的表格将看起来是空的);

  2. 当下载的图像在那里,发送一个刷新消息到你的表。

2,你有两种方法:

  1. 简单的一个:发送reloadData到你的表格视图(并检查你的应用程序的性能);

  2. 发送你的表查看消息:

     - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation 

使用reloadRowsAtIndexPaths要好得多,但是需要跟踪哪个图像与哪个表格行相关联。

请记住,如果您使用Core Data存储图像,那么通过将NSFetchedResultController与您的表视图集成将使这个工作stream程变得更容易。 看这里的例子 。

再一种方法是使用KVO:

  1. 在ItemsViewCell中声明这个观察方法:

     - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqual:@"thumbnail"]) { UIImage* newImage = [change objectForKey:NSKeyValueChangeNewKey]; if (newImage != (id)[NSNull null]) { self.thumbContainer.image = newImage; [self.thumbContainer setNeedsLayout]; } } } 
  2. 那么当你configuration单元的时候呢:

     RSSItem *item = [[channel items] objectAtIndex:[indexPath row]]; cell.titleLabel.text = [item title]; cell.thumbContainer.image = [item thumbnail]; [item addObserver:cell forKeyPath:@"thumbnail" options:NSKeyValueObservingOptionNew context:NULL]; 

通过这样做,每当给定item “缩略图”键path改变时, cell将被通知。

另一个必要的改变是这样做的任务:

  self.thumbnail = [UIImage imageWithData:tempData]; 

(即使用self. )。

另一编辑:

我想下载和加载图像就像苹果的LazyTableImages示例。 当不减速和拖动,只有屏幕上的图像加载,并不是所有的图像一次加载。

我怀疑我们在这里谈论不同的问题。

我以为你的问题是,下载的图像显示不正确(如果你不滚动表)。 这是我从你的问题中了解到的,我的build议修复了这个问题。

至于延迟加载,你在做什么(下载整个提要,然后整体归档)和你想要什么(延迟加载)之间存在某种不匹配。 这两件事情不一致,所以你应该重新思考你在做什么。

除此之外,如果您想延迟加载图像,您可以按照下列步骤操作:

  1. 不要在parser:foundCDATA:加载图像parser:foundCDATA:只是存储图像的URL;

  2. 开始下载tableView:cellForRowAtIndexPath:的图像tableView:cellForRowAtIndexPath:如果你知道的URL,你可以使用dataWithContentOfURL,因为你正在做一个单独的线程);

  3. 我上面发布的代码将使图像在那里时表更新;

  4. 首先,不要担心滚动/拖动,只要1-2-3工作;

  5. 一旦工作,使用滚动/拖动代表来防止图像在滚动/拖动期间下载(点2); 您可以添加一个标志到您的表视图,并使tableView:cellForRowAtIndexPath:只有在标志显示“不滚动/拖动”下载图像。

我希望这足以让你达到最终结果。 我不会为此编写代码,因为它非常简单。

PS:如果您懒惰加载图像,您的饲料将存储在磁盘上没有图像; 你可以把CGD组和CGD等一下。 正如我所说,没有办法,你不能做延迟加载,并在同一时间存档图像与饲料(除非每次你得到一个新的形象,你存档整个饲料)。 你应该find另一种caching图像的方法。

尝试使用SDWebImage ,它非常适合在UITableViews中使用来自Web的图像,并为您处理大部分工作。

最好的想法是caching图像并使用它们。 我已经写了表视图的代码。 在单元格顶部的图像这是一个很好的解决scheme。

尝试使用此代码下载图片,

  - (void) downloadThumbnails:(NSURL *)finalUrl { NSURLRequest* request = [NSURLRequest requestWithURL:finalUrl]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * error) { if (!error) { thumbnail = [UIImage imageWithData:data]; } }]; }