当图像保存在核心数据的集合视图中时,应用程序因内存错误而崩溃
Posted
技术标签:
【中文标题】当图像保存在核心数据的集合视图中时,应用程序因内存错误而崩溃【英文标题】:App crashes due to memory error when images are held in a collection view from core data 【发布时间】:2014-01-20 04:09:08 【问题描述】:我正在从核心数据中将图像添加到集合视图中,该核心数据从 uiimagepicker 中获取图像。但是,当我将超过 6 张图像加载到我的应用程序中时,它会占用大部分内存,有时还会崩溃。除了获取它们并将它们直接放入具有 100x100 图像视图的单元格中的集合视图之外,我没有对图像做任何事情。有谁知道我可以做些什么来减少内存并使应用程序不会崩溃?
代码sn-ps:
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
return 1;
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
return _fetchedObjects.count;
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
PhotosCollectionViewCell * cell = (PhotosCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"photoCell" forIndexPath:indexPath];
NSManagedObject *object = [_fetchedObjects objectAtIndex:indexPath.row];
cell.cellImage.image = [UIImage imageWithData:[object valueForKey:@"image"]];
return cell;
其他类:
Photo * photoEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:_context];
NSError * error;
NSData *imageData = UIImagePNGRepresentation(_image);
photoEntity.name = _nameField.text;
photoEntity.image = imageData;
photoEntity.imagedescription = _descriptionField.text;
if (![_context save:&error])
NSLog(@"There was a save error:%@",error);
[self dismissViewControllerAnimated:YES completion:nil];
谢谢
【问题讨论】:
存储的图像大小是多少?如果图像视图为 100 x 100,则显示时需要缩小图像尺寸。 @iCoder 我希望在您单击图像时仍然保持更高的分辨率。可以两者兼得吗? 我已经回答了同样的问题 [这里][1] [1]:***.com/questions/17161755/…希望这会有所帮助! 你的图片是什么格式的,尺寸是多少? 【参考方案1】:不要将图像存储在 Core Data 中。他们占用了太多的内存!如果将属性之一是图像的对象读入内存,则将该图像读入内存。因此,如果您有 100 个对象并获取它们的名称,那么您还会将 100 个图像加载到内存中,这可能会导致您的应用程序崩溃。
在 Core Data 中,将 references 存储到图像。将实际图像存储在其他地方,例如在磁盘上。
【讨论】:
我是否使用 xcdata 文件中的允许外部存储选项来执行此操作? @Sam:我认为 matt 的意思是你应该只将文件路径存储在 Core Data 中,而不是实际的图像文件。【参考方案2】:您需要将高分辨率图像与您在集合视图中使用的预览分开。
只需将高分辨率数据从Photo
对象中提取到关系背后的单独实体即可。我们称这第二个实体为ImageData
。它将有一个属性imageData
并选中“允许外部存储”选项。 Photo
与ImageData
有关系,ImageData
与Photo
有反比关系。
Photo
将有一个小版本的图像。分辨率刚好够细胞使用。勾选“Allows external storage for it”也没有什么坏处,Core Data 会决定在哪里存储它。
现在,当您为集合视图获取 Photo
对象时,您将只加载小版本的图像。默认情况下,ImageData
的关系本身会出错,关系另一端的对象也会出错。
当用户单击单元格并显示一些细节视图控制器时,您将拍摄这张照片并使用它的属性来获取大图像photo.imageData.imageData
。并且只有在这个时候故障才触发,并且大图像被加载到内存中。
【讨论】:
以上是关于当图像保存在核心数据的集合视图中时,应用程序因内存错误而崩溃的主要内容,如果未能解决你的问题,请参考以下文章
当更新版本已经在内存中时,强制核心数据从以前存储的版本刷新 NSManagedObject
当我们保存在 NSUserDefaults 中时,从核心数据和应用程序中获取“<NULL>”数据会崩溃?