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
【讨论】:
在更新图像视图之前,确保特定indexPath
的cell
仍在屏幕上并且没有被另一个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 中异步加载图像 - 自动布局问题