UITableViewCell 内存问题中的异步图像加载

Posted

技术标签:

【中文标题】UITableViewCell 内存问题中的异步图像加载【英文标题】:Asynchronous image loading in UITableViewCell memory issue 【发布时间】:2013-01-04 05:55:50 【问题描述】:

在我的 iPhone 应用程序中,我有一个带有自定义图像视图的表格视图,并使用 AsyncImageView 类从远程位置加载图像。它工作得很好,但一个问题是,如果我滚动表格,单元格将出列,并且它再次尝试从服务器获取图像。因此,从 AsyncImageView 类中加载图像的方法一次又一次地调用,从而增加了内存分配,最终导致应用崩溃。

这是我的代码:

- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier 

    CGRect CellFrame = CGRectMake(0, 0, 300, 40);

    CGRect userImageFrame = CGRectMake(5, 7, 36, 36);

    UIImageView *userImage;

    UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
    [cell setFrame:CellFrame];

    userImage = [[UIImageView alloc]init];
    userImage.frame = userImageFrame;
    userImage.tag = 3;
    [cell.contentView addSubview:userImage];
    [userImage release];

    return cell;


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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)
        cell = [self getCellContentView:CellIdentifier];
    else
        [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:cell.imageView];

    UIImageView *userImage = (UIImageView *)[cell viewWithTag:3];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.selectionStyle = UITableViewCellSelectionStyleGray;
    NSString *url = [[NSString alloc]initWithFormat:@"%@%@", CommonImageURL,[AllUsersProfileImageArray objectAtIndex:indexPath.row]];
    NSURL *imageUrl =  [NSURL URLWithString:[url stringByAppendingFormat:@"?%i", rand()]];
    [url release];

    userImage.image = [UIImage imageNamed:@"defaultPerson.png"];
    userImage.imageURL = imageUrl;
    return cell;

有没有办法解决这个问题?请帮忙。

【问题讨论】:

如果有人需要有关问题或代码的更多信息,请告诉我。 您是在寻找内存泄漏搜索指南还是寻找更好的图像加载解决方案? 我使用了 EGOImageView,现在使用了 AsyncImageView。功能方面两者都很好。但问题在于内存分配。我只是想避免不断增加的内存分配问题。 您是否进行了泄漏检查?如果是这样,您可能需要获得一些磁盘缓存以最大程度地减少内存使用量,如果不打算重复使用,还可以考虑调整(缩小)加载图像的大小,这样可以节省一些内存并提高性能。跨度> 我找不到泄漏问题,但它正在增加分配。将尝试调整图像大小。谢谢。 【参考方案1】:

最好的解决方案是缓存已经下载的图像并从那里显示。

你需要为此编写代码,或者有一些库提供这样的功能:

    HJCache SDWebImage

【讨论】:

在更新图像视图之前,确保特定indexPathcell 仍在屏幕上并且没有被另一个indexPath 重复使用非常重要。这些异步图像下载器中的许多都没有这样做,而只是愉快地更新图像视图。一个好的实现应该允许completion 块(或委托),我们可以在其中确认indexPath 在更新之前仍然可见。这些中的任何一个都这样做吗?这是一个如此基本的问题,肯定有些图书馆必须优雅地处理这个问题。哪些库处理得最好? 感谢您的参考,现在我正在使用 SDWebImage。但是某些类出现了一些错误,例如 Apple Mach-O Linker Error。 @Rob:感谢您的宝贵意见,我以前用过HJCash,它可以解决这个问题,而且是一个非常好的库 我必须添加 ImageIO 框架才能使其正常工作,现在没有错误 :) @Mithuzz:感谢您的评论 :)【参考方案2】:

流行的AFNetworking 库还包括一个 UIImageView 类别,用于从网络加载图像,这经常被忽视。我发现它在内存使用方面非常有效且易于使用。

http://afnetworking.github.com/AFNetworking/Categories/UIImageView+AFNetworking.html

【讨论】:

【参考方案3】:

我遇到了同样的内存泄漏问题,从服务器加载多个图像。我的应用程序每次都需要新鲜的图像响应(功能因素) 我正在使用 NSURLConnection 使用异步请求。我试过了

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:0];
[NSURLCache setSharedURLCache:sharedCache]; // in DidFinishLoading & didFailWithError

receivedData=nil;  // at didReceiveResponse
receivedData=[[NSMutableData alloc] init];

但没有任何帮助,直到我移除了我的牢房 [cell removeFromSuperview]; 在 cellForRowAtIndexPath 中并为 每一个新的 NSURL 请求再次初始化它(如果条件在 cellForRowAtIndexPath 上附加,但确实得到了回报)。

可能 UIImageViews 从未被删除,并且新的图像和数据会不断地添加,就像响应获取的一样。在我的情况下,为新的 NSURLRequest 删除旧的 UITableViewCell 是可行的。 希望这有助于像我这样迷失在清理 NSURLCache 并且仍在增加内存的人。

【讨论】:

【参考方案4】:

我在这里发布了一个自定义解决方案 Download image asynchronously.

我认为它工作正常,并且只需要很少的代码。

【讨论】:

以上是关于UITableViewCell 内存问题中的异步图像加载的主要内容,如果未能解决你的问题,请参考以下文章

Swift:在 UITableViewCell 中异步加载图像 - 自动布局问题

优化 UITableViewCell 上的绘图

UITableViewCell 异步图片加载布局

UITableViewCell 的异步高度更改

自定义 UITableViewCell - UIImageView 的异步 UIImage

如何在 iOS 中异步向 UITableViewCell 添加视图?