通过dispatch_async获取图像数据后刷新UITableViewCell

时间:2014-12-09 18:00:36

标签: ios objective-c uitableview setneedsdisplay

我正在编写显示TableView的应用程序,其中包含包含图像的条目。 我试图通过在cellForRowAtIndexPath方法中执行以下代码来获取图像:

cell.detailTextLabel.text =  [artistData objectForKey:generesKey];
dispatch_async(backgroundQueue, ^{
         NSURL *url_img = [NSURL URLWithString:[artistData objectForKey:pictureKey]];
        NSData* data = [NSData dataWithContentsOfURL:
                         url_img];
        cell.imageView.image = [UIImage imageWithData:data];
        [self performSelectorOnMainThread:@selector(refreshCell:) withObject:cell waitUntilDone:YES];
    });

设置图像后,我执行包含以下内容的选择器:

-(void)refreshCell:(UITableViewCell*)cell{
    [cell setNeedsDisplay];
    [self.view setNeedsDisplay];
    [self.tableViewOutlet setNeedsDisplay];
}

图像未显示但是当我点击单元格或滚动整个列表时,会显示图像。为什么我的视图不清爽?我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

您可以随时通过调用[self.tableView reloadRowsAtIndexPaths@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

重新加载单元格

为了在成功下载图像后阻止无限循环,您需要缓存结果。你缓存的时间取决于你。

 NSCache *imageCache = [[NSCache alloc] init];
 imageCache.name = @"My Image Cache";
 UIImage *image = [imageCache objectForKey:url_img];
 if (image) {
    cell.imageView.image = image;
 } else {
    // Do your dispatch async to fetch the image.

    // Once you get the image do
    [imageCache setObject:[UIImage imageWithData:data] forKey:url_img];
}

您希望imageCache成为ViewController级别的属性。不要在cellForRowAtIndexPath

中每次创建一个

答案 1 :(得分:1)

在单元格上调用 setNeedsLayout() 就足够了。

swift 中,它看起来像这样:

DispatchQueue.global().async {
    let data = try? Data(contentsOf: URL(string: imageUrl)!)
    DispatchQueue.main.async {
        cell.imageView?.image = UIImage(data: data!)
        cell.setNeedsLayout()
    }
}

答案 2 :(得分:0)

它可能与从后台队列中与UI交互有关。试试这个:

dispatch_async(backgroundQueue, ^{
    NSURL *url_img = [NSURL URLWithString:[artistData objectForKey:pictureKey]];
    NSData* data = [NSData dataWithContentsOfURL:url_img];
    dispatch_async(dispatch_get_main_queue(), ^{
        cell.imageView.image = [UIImage imageWithData:data];
    });
});