我刚接触GCD工作,我很难理解我在这里做的事情是否正确。
当我配置一个单元格时,我想从托管对象中提取一个URL,然后将一个块发送到GCD以下拉驻留在该URL的缩略图图像。
图像下载后,我将在第一个块中调度另一个块,将下载的缩略图放入单元格中。
当表格显示在屏幕上时,我希望在每个单元格的缩略图中看到一个活动微调器,缩略图随后会在完成下载后替换为实际图像。
实际发生的是,单元格出现在TableView中,我看不到微调器。但是,如果我单击一个单元格,图像会突然出现。同样,如果我离开该视图然后再次显示它。另外,当我向上和向下滚动TableView时,会发生一些非常奇怪的事情 - 缩略图似乎“重复”然后在我滚动时重新下载。
我很抱歉,如果这有点难以解释,但我不知道如何最好地描述我所看到的。
如果有人可以查看代码并且可能就可能出现的问题提出一些建议,我会很感激:
if([managedObject isKindOfClass:[Photo class]])
{
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[cell.imageView addSubview:spinner];
[spinner startAnimating];
Photo *photo = (Photo *)managedObject;
NSString *URLString = photo.thumbnailURL;
dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_queue_t downloadQueue = dispatch_queue_create("Thumb downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:URLString];
dispatch_async(callerQueue, ^{
UIImage *thumbImage = [UIImage imageWithData:imageData];
[spinner stopAnimating];
cell.imageView.image = thumbImage;
[cell.imageView setNeedsDisplay];
});
});
dispatch_release(downloadQueue);
}
return cell;
答案 0 :(得分:4)
在后台加载数据后(在本例中为图像),您不应直接访问单元格。如果在加载数据之前滚动屏幕,则它无效。您应该在数据加载方式上设置机制,并在它返回时调用[tableView reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation]
。
答案 1 :(得分:1)
[cell.imageView addSubview:spinner];
上面的线条闻起来不像它会起作用。请尝试[cell.contentView addSubview:spinner];
。您可能需要更改微调器的frame.origin才能将其放在正确的位置。
缩略图似乎“重复”,然后在滚动时重新下载。
由于您的tableViewCells正在被重用,因此下载的图像与原始获取请求的单元格不匹配。
在内部,内部块中,您需要验证单元格是否仍然对应于您认为的托管对象/照片/索引路径。
其他:
[spinner stopAnimating]
之后您可能需要[spinner removeFromSuperview]