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

时间:2014-04-13 19:25:18

标签: ios objective-c uitableview asynchronous sdwebimage

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

我想按索引路径优先处理图像下载,因此第一个索引路径优先于第二个索引路径,优先于第三个索引路径,等等。

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

我该如何设计这样的东西?如果SDWebImage可能会很好,那我就会很满意,但如果不是,我可以通过{{{{{{{{{{{{{{{{{{{{{{{{{{{ 1}}。 (我已查看NSURLSession,而SDWebImage看起来很有希望,但不允许优先级从我所看到的情况发生变化。)

1 个答案:

答案 0 :(得分:0)

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

我可以想到两个选择:

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

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

  3. 我使用NSCache做了选项二。 key" 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"]];
                        }
                    });
                }
            }
        });
    }
    

    }