2014-03-31 135 views
1

我正在开发一个应用程序UICollectionView在一个ViewControllerUICollectionView滚动时收到内存警告

This CollectionView这是一个画廊,每行3个图像。

CollectionView

我从服务器获取图像中的30张图片,第一网页地址和代码组,当细胞将被显示在cellForItemAtIndexPath我用SDWebImage Library异步下载那些图片。每30张图片我再次调用Web服务,并且我获得30张图片,并发送带有限制和偏移量的请求。这可能发生100次,有3000张图片的配置文件。

好吧,我的问题来了一个我启动应用程序在我的iPhone 4,一些快速滚动后,我开始得到Received Memory Warnings和一些警告后,应用程序崩溃。当我在模拟器中进行相同的测试时,没有什么不好的事情发生。

每次我下载30幅图象I添加结果数组到它处理CollectionView数据和reloadcollectionViewNSMutableArray *data property。我试图用分配的仪器,但是我很难理解正在发生的事情。

这是我用来创建细胞

-(UICollectionViewCell *)collectionView:(LZProfileImagesCollectionView *)aCollectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    if(aCollectionView == self.imagesCollectionView){ 
     if([self.data count] - 12 == indexPath.row){ 
      self.photoOffset += 30; 
      [self loadUserData]; 
     } 

     LZProfileCollectionViewCell * cell = (LZProfileCollectionViewCell *)[imagesCollectionView dequeueReusableCellWithReuseIdentifier:ImageCollectionCellIdentifier forIndexPath:indexPath]; 
     Image *image =(self.data)[indexPath.row]; 
     [cell configureCellWithImage:image]; 

     return cell; 
    } 
    return nil; 
} 

的代码和LZProfileCollectionViewCell细胞我有这样的一个:

-(void)configureCellWithImage:(Image *)image 
{ 
    [self setNeedsDisplay]; 

    // Imagen 
    NSString *imageUrl = [kBaseURL stringByAppendingString:image.imageStringUrl]; 
    [self.pictureImg setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:kDefaultLoadingImage]]; 
    [self.pictureImg setContentMode:UIViewContentModeScaleAspectFit]; 

} 

我采取setImageWithURLSDWebImage

3后几分钟我在仪器中获得此快照(统计)

Statistics

预先感谢您

+0

如果您正在使用第三方库,则由您来确保您已将其配置为进行适当的缓存。当您需要释放内存时,您还负责清除缓存。 Allocations工具对于使用内存的位置有何评论? –

+0

我对通常的请求使用了'AFNetworking',对图像异步下载使用了'SDWebImage'。在乐器配置中你想看到什么?调用树,分配列表? – croigsalvador

+0

从'Statistics'->'Object Summary'开始并查看顶部的'Live Bytes'对象。或张贴屏幕截图。以及一些堆镜头。 –

回答

0

好了,你正在缓存每个图像阵列中的,所以一旦您缓存这么多的图片你最终将耗尽内存。它不会在模拟器上发生,因为模拟器具有与运行它的计算机一样多的内存,所以它不可能耗尽内存,然而真正的设备会非常快地耗尽。我会自己处理内存错误并清空阵列,为新图像释放新空间。或者更好的是创建自己的缓存机制来保存和清除一段时间内没有看到的图像,无论哪种方式,您必须有某种方法才能在达到某个阈值后转储图像。

+0

但是..我的数组只保存图片的URL和代码,而不是图片本身 – croigsalvador

+0

这不是正确的答案,问题是你永远不会释放每个单元格中加载的图像 – Gabox

0

在方法– didReceiveMemoryWarning你应该释放你存储图像的阵列的一些内存。也许你没有显示的第一张图像存储了第二个数组,像一个辅助数组。

+0

但是,如果我再次向上滚动,我应该再次替换数组中的项目,不是吗? – croigsalvador

0

这可能是因为很多UIImage对象最终在内存中。您可以将其缓存在磁盘上。 AFNetworking有一个不错的UIImageView category自动完成所有这一切。

如果您没有将图像保存到dataSource数组中,那么它们可能被保留在其他地方,这是一个错误。

此外,请确保您是dequeuing单元格,而不是创建新单元格。

+0

我使用'setImageWithURL' SDWebImage Library方法。它是否相似? – croigsalvador

+0

它们的最终效果可能相似,但我不确定SDWebImage是否执行磁盘缓存。 – rounak

+0

SDWebImage **具有自动缓存过期处理的异步内存+磁盘映像缓存** https://github.com/rs/SDWebImage – croigsalvador

0

我遇到类似的情况,所以我在这个问题上回答,虽然理由似乎有点不同于你的。

我在UITableViewCell中有一个水平的UICollectionView。当我快速左右滚动UICollectionView时,整个用户界面(甚至主页按钮)停止,一段时间后,应用程序崩溃,即使没有didReceiveMemoryWarning调用,控制台上的消息“来自调试器的消息:终止,由于内存问题”。

我使用UICollectionViewCell对其进行了测试,没有任何UI组件,但没有更改。 XCode Profile工具说,它实际上是在UI停止的时候继续分配内存,直到它崩溃,即使没有任何UI组件。

唯一可疑点是,我是与设置UICollectionViewCell的子视图的(自定义的UIView固定到所有上海华边缘)的宽度AppDelegate.window.size.width * 0.35确定UICollectionViewCell的宽度,这是一个浮点值像130.25

当我把这个值硬编码为130时,所有的崩溃都消失了。我认为这个模糊的值是130.25,并且它偶尔会将宽度确定为130或130.25。

所以我使用CGFloat(Int(AppDelegate.window.size.width * 0.35))现在,一切都很好。