我尝试在coredata和FetchedResultsController的帮助下构建一个表视图(来自coredata的信息是从服务器获取API),表中的每个单元都有一个图像视图,它从GCD网络异步加载图像(也是我在方法中尝试并使用SDWebImage) “tableView:tableView cellForRowAtIndexPath:indexPath”,当我发出更多记录的另一个请求时出现问题(例如,我第一次有50条记录,当我做一个新请求并将其保存在核心数据中时,图像不再正确关联有文章或在滚动时消失)我相信因为fetchedResultsController的结果是按时间函数排序的。 我的代码:
NewsFeed *singleFeed = [self.fetchedResultsController objectAtIndexPath:indexPath];
NLNewsFeedCell *cell = (NLNewsFeedCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"NewsFeedCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.lblTextContain.numberOfLines = 0;
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:singleFeed.urlPicture]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
cell.imgPicture.image = image;
[cell setNeedsLayout];
});
}
});
}
任何建议,如何解决这个问题? 谢谢,抱歉拼写错误。
答案 0 :(得分:1)
首先,检查重复使用的单元格:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
如果单元格为nil
,请创建新单元格。如果不是nil
则使用现有的。
其次,我建议您创建一个处理图像下载的自定义单元格,可以取消下载或忽略下载。
您的问题是由于在加载单元格后完成下载并且可能已完成对不再可见的单元格的下载这一事实引起的。
您可以使用AFNetworking或支持下载取消的任何其他异步图像加载库,并在自定义单元格的-(void)prepareForReuse
方法(在重复使用单元格之前调用)中取消旧的下载操作因此,当单元格加载时,它将使用上次下载操作的图像。
答案 1 :(得分:1)
如果在经典cellForRowAtINdexPath
内执行此操作,我注意到其他代码,我注意到可能有错误。
每次显示单元格时,您总是从网上下载图像,这可能会发生多次,具体取决于您向上和向下滚动UITableView的次数。如果您没有实现任何URLCache,这可能会导致不必要的网络操作,如果服务器以no-cache响应,则会导致最糟糕的情况。您应该构建一种本地下载程序,它只异步加载映像一次并存储在缓存中,并阻止同一资源的任何后续请求。
考虑到您的问题,请不要忘记重复使用细胞。这意味着将使用新数据再次创建和重新填充UITableCell。
我发现在我的自定义类单元格中实现prepareForReuse
以清除为先前实体继承的任何资源非常有用。否则,除非下载完成并替换图像,否则您将看到旧图像。