如何为我的 UITableView 设计一个异步图像下载器,根据表格视图中的位置优先下载?

Posted

技术标签:

【中文标题】如何为我的 UITableView 设计一个异步图像下载器,根据表格视图中的位置优先下载?【英文标题】:How would I design an asynchronous image downloader for my UITableView that prioritizes downloads depending on location in table view? 【发布时间】:2014-05-27 15:52:09 【问题描述】:

在我的应用程序中,我收到一个图像 URL 列表,可用作表格视图中的缩略图。 tableview 有少量项目,大约 30 个,所以我想立即加载所有缩略图(而不是在它们变得可见时,因为它们无疑会变得可见,然后我希望它们完全加载)。

我想通过索引路径优先考虑图像下载,所以第一个索引路径优先于第二个,第二个优先于第三个,等等。

但是,如果我突然跳到表格视图的末尾(例如,显示索引路径 24-29),我希望这些索引路径的图像成为最高优先级,所以如果他们从一开始就跳,他们不必等待所有其他人先下载。

我将如何设计这样的东西?如果SDWebImage 可以,那就太好了,因为我对此很满意,但如果不是,我可以用NSURLSession 从头开始​​创建一些东西。 (我看过SDWebImageSDWebImagePrefetcher 看起来很有希望,但不允许改变我所看到的优先级。)

【问题讨论】:

SDWebImage 正在使用NSOperation 子类和NSOperationQueue,因此假设您可以在SDWebImageDownloader 中提供公共方法来更改操作的队列优先级。但是,我认为这不会影响已经执行的操作;我相信您必须取消并重新启动这些。 【参考方案1】:

我最近遇到了类似的问题,但不需要优先加载。除非您在加载表格视图之前加载缩略图,否则我想不出如何更改加载内容的优先级。表格视图根据需要加载单元格。

我能想到两个选择:

    如果您希望在加载 tableview 之前加载并准备好所有数据,请先将数据加载到较早的视图控制器中,然后将其保存以在包含表视图的视图控制器中打开。然后,您的 tableview 将无需发出任何请求,一切都会无缝显示。

    tableview 异步发送每个缩略图请求,并在图像到达主线程时更新单元格。然后,您可以在图像到达后缓存或保存图像。但图像不会立即出现,通常会在一瞬间之后。

我使用 NSCache 做了选项二。键“avatar”的值是缩略图的 URL。此代码位于我的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

if (![teamMember[@"avatar"] isEqualToString:@""]) 
    // check for cached image, use if it exists
    UIImage *cachedImage = [self.imageCache objectForKey:teamMember[@"avatar"]];
    if (cachedImage) 
        cell.memberImage.image = cachedImage;
    
    //else  retrieve the image from server
    else 
        NSURL *imageURL = [NSURL URLWithString:teamMember[@"avatar"]];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        // if valid data, create UIImage
        if (imageData) 
            UIImage *image = [UIImage imageWithData:imageData];
            // if valid image, update in tableview asynch
            if (image) 
                dispatch_async(dispatch_get_main_queue(), ^
                    TeamCommitsCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
                    // if valid cell, display image and add to cache
                    if (updateCell) 
                        updateCell.memberImage.image = image;
                        [self.imageCache setObject:image forKey:teamMember[@"avatar"]];
                    
                );
            
        
    );

【讨论】:

以上是关于如何为我的 UITableView 设计一个异步图像下载器,根据表格视图中的位置优先下载?的主要内容,如果未能解决你的问题,请参考以下文章

如何为我的静态 UITableView 添加页脚?

我如何为我的应用程序创建这样的“关于”页面?如何在 UIView 下拥有 UITableView(分组)?

如何为uitableview自定义多选编辑模式

如何为 UITableView 添加自定义 EditingAccessoryView?

如何为自定义 UITableView 标题部分笔尖添加分隔线? [复制]

如何为不和谐机器人调用异步函数