尝试将远程图像加载到表中但仍未正确缓存

时间:2012-08-27 23:01:02

标签: iphone image loading

我正在尝试将图像加载到表中,但我仍然在闪烁。图像正在加载,但在滚动时,在下一个缩略图图像加载之前会出现短暂的闪烁。是的,知道Apple有一个例子和各种框架,但这是超级简单的代码,只是在下载图像加载之前该死的闪烁。其他一切都很好。 谢谢!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"customCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil){
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil];

    for (id currentObject in topLevelObjects) {
        if ([currentObject isKindOfClass:[CustomCell class]]) {
            cell = (CustomCell *)currentObject;
            break;
        }
    }
}

NSString *myUrl = [[items objectAtIndex:indexPath.row] objectForKey:@"myUrl"];

NSURL *url = [NSURL URLWithString:url];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
    UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
    dispatch_sync(dispatch_get_main_queue(), ^{
        [[cell imageView] setImage:image];
        [cell setNeedsLayout];
    });
});

return cell;
}

2 个答案:

答案 0 :(得分:1)

您正在使用UITableView的重复使用机制。这意味着您可以从dequeueReusableCellWithIdentifier获取已有图像集的单元格。因此,首先您需要使用[[cell imageView] setImage:nil]删除图像。然后在调度块内部,您无法确定该单元格是否仍在屏幕上。您需要检查索引路径是否仍然相同,否则您将图像设置为错误的单元格:

dispatch_async(queue, ^{
    UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
    dispatch_sync(dispatch_get_main_queue(), ^{
        if ([[tableView indexPathForCell:cell] compare:indexPath] == NSOrderedSame) {
            [[cell imageView] setImage:image];
            [cell setNeedsLayout];
        }
// alternative:    
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (cell)
            cell.imageView.image = image;
    });
});

我建议使用NSOperation子类来加载远程图像而不是使用dataWithContentsOfURL - 然后您也可以在单元格离开时取消图像加载。 还要考虑使用图像缓存以获得更好的性能。

答案 1 :(得分:0)

我有一个类似的问题,您需要检查以查看图像是否已加载。您当前的代码只是加载图像,但如果单元格已经有图像怎么办?每次用户滚动表时,您都不希望执行此任务。

查看我提出的问题。

Table View Scrolling Async