由于某些原因,当我使用 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];
答案 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;