【问题标题】:Received memory warning in UICollectionView iOS 7在 UICollectionView iOS 7 中收到内存警告
【发布时间】:2014-01-03 08:25:05
【问题描述】:

我正在使用 UICollectionView 使用资产显示我的库中可用的所有图像,它显示所有图像但是当我多次上下滚动时,我在设备中收到内存问题,一段时间后它会崩溃说由于内存压力而崩溃 使用的代码如下

在这里创建collectionview并设置它的委托

UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
allPhotosCollectionView=[[UICollectionView alloc]initWithFrame:CGRectMake(5, 5, 310, 481)collectionViewLayout:layout];
[allPhotosCollectionView setDelegate:self];
[allPhotosCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
[allPhotosCollectionView setDataSource:self];
[self.view addSubview:allPhotosCollectionView];

委托方法

- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
return [allImageArray count];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
{
return 1;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:       (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath   *)indexPath
{
return CGSizeMake(95, 100);
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
NSString *identifier = @"Cell";
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
// allimageArray has the Assest URL fo the images
NSURL *aURL=[[NSURL alloc]initWithString:[NSString stringWithFormat:@"%@",[allImageArray objectAtIndex:indexPath.row]]];
[assestLibrary assetForURL:aURL resultBlock:^(ALAsset *asset)
 {
     UIImage  *copyOfOriginalImager = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:0.5 orientation:UIImageOrientationUp];
     UIImageView*imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 90, 90)];
     NSData *imageData;
     imageData=UIImageJPEGRepresentation(copyOfOriginalImager, 0.4);
     [imageView setImage:[UIImage imageWithData:imageData]];
  [cell.contentView addSubview:imageView];
  }
        failureBlock:^(NSError *error)
  {
     // error handling
     NSLog(@"failure-----");
    }];
  return cell;
  }

我在iOS 7中遇到很多问题,由于内存压力导致应用程序崩溃,请解释一下

【问题讨论】:

    标签: ios objective-c ios7 uicollectionview didreceivememorywarning


    【解决方案1】:

    由于评估库。一旦你使用 assest 库获取图像,只需将其存储在某个变量中并在

    中重新使用该图像
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    

    在滚动集合视图时,它会使用资源库一次又一次地获取图像,这将导致巨大的内存泄漏。

    编辑:

     UIImage *img =[imageDictionary objectForKey:imageName];
                    if(!img)
                    {
    
                        NSURL *asseturl = [NSURL URLWithString:imageName];
                        img = [McAssetReader readImage:asseturl];
                        [imageDictionary setObject:img forKey:imageName];
                    }
    

    其中 imageDictionary 是保存图像的 Global 字典。 imageName 是特定图像的 url。

    【讨论】:

    • 你是在告诉我将图像存储在数组中,然后在 cellForItemAtIndexPath 中使用它?
    • 是的,只需跟踪已使用资产库读取的图像。如果图像在本地变量中不可用,则使用资产库获取它,否则使用本地库中的图像。
    • @CoolMonster 如果它有 1000 多张图像,我们如何存储它?这是正确的做法吗?
    • @Mani,不,正确的方法是使用具有合理大小和清除策略的NSCache
    • k.为什么我们在这里使用 NSCache?他在任何地方都没有记忆吗?您在哪里看到持有图像?只有 10-15 个细胞始终保持活动状态,这意味着如何让所有图像在其中保持活动状态?
    【解决方案2】:

    您的代码有两个问题:

    • 您一直在将 imageViews 添加到单元格中,甚至没有检查是否已经存在,因此内存使用量正在迅速增长;

    • 您没有缓存图像转换的结果并在每个单元出队时继续读取/转换,因此您对磁盘 IO 和内存保持压力;

    缓存和重用技术很可能会解决您的问题。

    【讨论】:

    • 当收集单元重新加载时,所有单元都将解除分配,并且应该只存活低于 10-15 个单元?那么它将如何因keep adding imageViews 而崩溃?请您详细解释一下好吗?因为他在任何地方都没有图像记忆?
    • 引用自 UICollectionView 文档:If an existing cell was available for reuse, this method calls the cell’s prepareForReuse method instead.;所以这些 imageViews 只是不断堆叠,直到单元格被释放。
    • 能否请您参考本文档的适当主题?滚动时所有单元格都活着吗?您是尝试提及这一点还是其他技术点?
    • 看我的回答。你的回答也会对他有很大帮助。但不适用于这个问题。
    【解决方案3】:

    我可以在这里看到问题。肯定会导致内存错误。

    UIImageView*imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 90, 90)];
    .
    .
    .    
    [cell.contentView addSubview:imageView];
    

    看到这一行。您每次都在创建 imageView 并将该图像保存到 imageview 中。

    所以你可以这样做而不是第一行。

    UIImageView *imageView = [cell.contentView viewWithTag:ImageViewTag];
    if (!imageView)
    {
        imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 90, 90)];
        [cell.contentView addSubview:imageView];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 2015-07-15
      • 2013-03-05
      • 1970-01-01
      • 2011-04-30
      相关资源
      最近更新 更多