【问题标题】: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]:stackoverflow.com/questions/17161755/…希望这会有所帮助!
  • 你的图片是什么格式的,尺寸是多少?

标签: ios objective-c xcode core-data uicollectionview


【解决方案1】:

不要将图像存储在 Core Data 中。他们占用了太多的内存!如果将属性之一是图像的对象读入内存,则将该图像读入内存。因此,如果您有 100 个对象并获取它们的名称,那么您还会将 100 个图像加载到内存中,这可能会导致您的应用程序崩溃。

在 Core Data 中,将 references 存储到图像。将实际图像存储在其他地方,例如在磁盘上。

【讨论】:

  • 我是否使用 xcdata 文件中的允许外部存储选项来执行此操作?
  • @Sam:我认为 matt 的意思是你应该只将文件路径存储在 Core Data 中,而不是实际的图像文件。
【解决方案2】:

您需要将高分辨率图像与您在集合视图中使用的预览分开。

只需将高分辨率数据从Photo 对象中提取到关系背后的单独实体即可。我们称这第二个实体为ImageData。它将有一个属性imageData 并选中“允许外部存储”选项。 PhotoImageData 有关系,ImageDataPhoto 有反比关系。

Photo 将有一个小版本的图像。分辨率刚好够细胞使用。勾选“Allows external storage for it”也没有什么坏处,Core Data 会决定在哪里存储它。

现在,当您为集合视图获取 Photo 对象时,您将只加载小版本的图像。默认情况下,ImageData 的关系本身会出错,关系另一端的对象也会出错。

当用户单击单元格并显示一些细节视图控制器时,您将拍摄这张照片并使用它的属性来获取大图像photo.imageData.imageData。并且只有在这个时候故障才触发,并且大图像被加载到内存中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-02
    • 2013-08-12
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多