UITableView UIImageView图像闪烁 - iOS / Objective C

时间:2014-04-19 01:24:40

标签: ios objective-c

由于某些原因,当我使用 GCD 下载图像时,图像将随机开始闪烁。

我将在模拟器中重置内容设置并且它将工作一次,然后它将再次开始闪烁。

这是我正在使用的代码。我有重新加载,因为如果我不重新加载它,图像不会显示,直到我点击单元格。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
    NSURL *url = [NSURL URLWithString:self.entries.arrayimage];
    NSData *imgData = [NSData dataWithContentsOfURL:url];


    dispatch_sync(dispatch_get_main_queue(), ^(void) {
        cell.imageView.image = nil;
        UIImage *img = [UIImage imageWithData:imgData];
        cell.imageView.image = img;
        [self.tableView reloadData];

    });


});
return cell;
[self.tableView reloadData];

4 个答案:

答案 0 :(得分:1)

那是因为您正在使用dispatch_async(dispatch_get_global_queue从文件中异步加载imageData。在cellForRow中使用此样式加载图像将使单元格图像首先应该是之前的图像。然后完成异步加载,将调用dispatch_sync(dispatch_get_main_queue(),加载您想要的图像。因此,无论何时reloadData或任何其他方法调用cellForRow,单元格图像都会闪烁。

我知道你想在不阻塞主线程的情况下加载图片,但这不是一个好方法。

答案 1 :(得分:1)

查看用于延迟图像加载的Apple示例代码。此外,我检查了您的代码,发现您始终从URL下载图像。而不是在高速缓存中下载和保存图像,然后从本地高速缓存中的cellForRowAtIndexPath方法中下载时加载图像(如果可用)。

答案 2 :(得分:0)

此代码是cellForRowAtIndexPath:吗?

如果是这种情况,这里的问题是所有单元都无限地重新加载表。您不应该在reloadData触发的任何数据源方法中调用reloadData

你所拥有的基本上是一个无限循环的重新加载。 (reloadData触发cellForRowAtIndexPath:,再次触发reloadData)。

我的建议是使用外部组件作为aeskreis发布在他的评论中。

SDWebImage可能是最好的一个,它可以让你简化所有代码:

NSURL *url = [NSURL URLWithString:self.entries.arrayimage];
[cell.imageView setImageWithURL:url];

答案 3 :(得分:0)

好的伙计们我发现了问题。它不断重新加载导致闪烁的数据。而不是[self.tableView reloadData]我用这个方法替换它:

        [cell setNeedsLayout];

我相信这种方法会检测是否有任何更改,然后更新它(从我几个小时前的记忆中更新,所以它可能不是100%准确),但这解决了我的问题。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

dispatch_async(queue, ^{
    NSURL *url = [NSURL URLWithString:self.entries.arrayimage];
    NSData *imgData = [NSData dataWithContentsOfURL:url];

    dispatch_sync(dispatch_get_main_queue(), ^{
        UIImage *img = [UIImage imageWithData:imgData];
        cell.imageView.image = img;
        //[self.tableView reloadData];
        [cell setNeedsLayout];
    });
});
return cell;