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

发布于 2025-01-07 06:46:33 字数 2424 浏览 0 评论 0原文

我看到一些帖子建议在异步下载图像的块中使用类似以下内容的内容,以便在主线程上调用 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

有什么想法吗?

I have seen a few posts which suggest using something like the following inside the block which downloads the images asynchronously in order to invoke setNeedsDisplayon the main thread and get it to display quicker.

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

I'm trying this as can be seen below but the images are not being displayed as soon as they are downloaded. Generally there is about a 4 - 5 second delay. I know this because if I select any particular row, the image appears while the others are still not displayed.

-(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;
}

Incidentally, the NSLog(@"background"); and NSLog(@"main thread"); calls below are printed in the following order for the call for the initial 6 cells, which is what I would expect, I think. But still doesn't work:

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

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丿*梦醉红颜 2025-01-14 06:46:33

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

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

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

Try to set downloaded image in main thread.

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

Also it is better to add images as subviews not for cell but cell.contentView.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文