cellForRowAtIndexPath:setNeedsDisplay 不适用于在后台下载的图像,即使在主线程上调用它也是如此

Posted

技术标签:

【中文标题】cellForRowAtIndexPath:setNeedsDisplay 不适用于在后台下载的图像,即使在主线程上调用它也是如此【英文标题】:cellForRowAtIndexPath: setNeedsDisplay not working for images downloaded in the background, even when calling it on the main thread 【发布时间】:2012-02-17 20:57:57 【问题描述】:

我看到一些帖子建议在异步下载图像的块内使用类似以下的内容,以便在主线程上调用 setNeedsDisplay 并让它更快地显示。

dispatch_async(main_queue, ^
                [view setNeedsDisplay];
            );

我正在尝试此操作,如下所示,但图像在下载后并未立即显示。通常有大约 4 - 5 秒的延迟。我知道这一点,因为如果我选择任何特定的行,图像就会出现,而其他图像仍然不显示。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath


    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    

    UIImageView *iv = (UIImageView*)[cell viewWithTag:kCellSubViewWavImageView];;

        //async for scroll performance
        dispatch_queue_t queue = 
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^

            NSURL *url = [[NSURL alloc] initWithString:[self.user.favWavformURLAr objectAtIndex:indexPath.row]];
            NSLog(@"background");
            NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];
            UIImage *image = [[UIImage alloc] initWithData:imageData];

            iv.image = image;

            dispatch_queue_t main_queue = dispatch_get_main_queue();
            dispatch_async(main_queue, ^
                NSLog(@"main thread");
                [iv setNeedsDisplay];
            );

        );

    

    return cell;

顺便说一下,下面的 NSLog(@"background");NSLog(@"main thread"); 调用按以下顺序打印,用于调用最初的 6 个单元格,我认为这是我所期望的。但还是不行:

2012-02-17 20:46:27.120 SoundcloudFavs[8836:1c03] background
2012-02-17 20:46:27.169 SoundcloudFavs[8836:1b03] background
2012-02-17 20:46:27.170 SoundcloudFavs[8836:6b07] background
2012-02-17 20:46:27.173 SoundcloudFavs[8836:7503] background
2012-02-17 20:46:27.174 SoundcloudFavs[8836:7103] background
2012-02-17 20:46:27.177 SoundcloudFavs[8836:8003] background
2012-02-17 20:46:27.219 SoundcloudFavs[8836:207] main thread
2012-02-17 20:46:27.270 SoundcloudFavs[8836:207] main thread
2012-02-17 20:46:27.282 SoundcloudFavs[8836:207] main thread
2012-02-17 20:46:27.285 SoundcloudFavs[8836:207] main thread
2012-02-17 20:46:27.296 SoundcloudFavs[8836:207] main thread
2012-02-17 20:46:27.300 SoundcloudFavs[8836:207] main thread

有什么想法吗?

【问题讨论】:

【参考方案1】:

尝试在主线程中设置下载的图像。

dispatch_async(main_queue, ^
            NSLog(@"main thread");
            iv.image = image;
        );

此外,最好将图像添加为子视图,而不是单元格,而是 cell.contentView

【讨论】:

非常感谢... 成功了!不敢相信我没想到。

以上是关于cellForRowAtIndexPath:setNeedsDisplay 不适用于在后台下载的图像,即使在主线程上调用它也是如此的主要内容,如果未能解决你的问题,请参考以下文章

从 cellForRowAtIndexPath 中调用 heightForRowAtIndexPath?

cellForRowAtIndexPath:reloaddata 未调用

tableView:cellForRowAtIndexPath 的保留计数:

UITableView tableView:cellForRowAtIndexPath:没有被调用

nib 项目中的 CellForRowAtIndexPath

无法在 tableView:cellForRowAtIndexPath: 方法中设置标签框