在 UICollectionView iOS 7 中收到内存警告
Posted
技术标签:
【中文标题】在 UICollectionView iOS 7 中收到内存警告【英文标题】:Received memory warning in 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中遇到很多问题,由于内存压力导致应用程序崩溃,请解释一下
【问题讨论】:
【参考方案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];
【讨论】:
以上是关于在 UICollectionView iOS 7 中收到内存警告的主要内容,如果未能解决你的问题,请参考以下文章
使用 iOS 7 的 UICollectionView?边距空间
iOS 7.1 在 UIPopover 中嵌套 UICollectionView
在 iOS 7 上运行时 UICollectionView 不显示