在 Core Data 中保存 UIImage 的最佳方法

Posted

技术标签:

【中文标题】在 Core Data 中保存 UIImage 的最佳方法【英文标题】:Best way to save UIImages in Core Data 【发布时间】:2014-05-04 20:27:18 【问题描述】:

我正在寻找将多个图像存储在一个核心数据对象中的最佳方法。我尝试将 UIImage 对象直接存储在 Core Data 中。工作正常!

尽管如此,我在一些论坛中阅读了将 UIImage 数据转换为 PNG 并将其存储为二进制数据的信息。在我的 iPhone 5s 上,这非常慢。

有什么好处和坏处?还有其他解决方案吗?

谢谢!

【问题讨论】:

【参考方案1】:

如果您的目标是 ios 6.0 或更高版本或 OSX 10.8 或更高版本,您可以打开允许外部存储(选择您的属性并查看 Data Model Inspector Core Data 模型编辑器)并让 Core Data 决定是否要将您的图像数据存储在数据库中或外部文件中(如果它超过一定大小)。

【讨论】:

我试过这个,但在我需要存储核心数据的时候它并没有改变任何东西。在我的测试中,我存储了 5 张来自 iPhone 5s 相机的图像。 抱歉,这是允许外部存储选项,而不是存储在外部记录文件中选项。我更正了答案。 我将“允许外部存储”与更好的图像处理(压缩)结合使用。谢谢!【参考方案2】:

将图像保存到数据库的好方法只有一种,不要这样做。

只需将其写入某个文件夹中的文件并仅存储文件名(或相对路径)。不要存储绝对文件路径,这会在从应用商店更新应用时导致问题。

推理:

    与其他类型的数据相比,图像数据量很大。它使托管对象的保存(和加载)显着变慢。独立于数据库代码的图像加载/保存非常有帮助。您可以加载对象元数据或按元数据搜索并仅在需要时加载实际图像(最慢的操作)。

    数据库中不需要有图像,您永远不会按数据搜索图像。

【讨论】:

【参考方案3】:

不要在 Core Data 中存储图像。将图像的路径存储在 Core Data 中。

您可以将任何图像保存到您的application sandbox 的LibraryDocuments 目录中。

简单示例:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryDirectory = [paths objectAtIndex:0];
NSString *path = [libraryDirectory stringByAppendingPathComponent:fileName];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:path atomically:YES];

// Save file name to Core Data. Don't store absolute paths.

【讨论】:

听起来是一种可行的方法。我明天试一试,告诉你我的经验。 为什么不在Core Data中保存绝对路径? @Leandros @TiagoAmaral 更新后文档目录的位置发生了变化,所以你保存文件名,然后每次获取文档目录的路径。【参考方案4】:

在不损失太多性能的情况下使用 Core Data 管理图像的一些技巧:

如果您的图像非常小(~100 ko),则将其与与图像相关的其他信息存储在同一实体中。

否则我建议你只将图片的路径存储在CoreData中并保存在设备中。

否则,如果您真的想将图像保留在CoreData中而不管其大小,您能否向我们展示一下非常慢的代码?

【讨论】:

我刚刚将 UIImage 转换为 PNG 原始数据并将其存储为 NSData。在 for 循环中,我刚刚为所有图像(最多 5 个图像)调用了 [imgData addObject:UIImagePNGRepresentation(img)]。 不,我用同样的方法存储核心数据。我虽然在后台进行更新时会与更新视图发生冲突。

以上是关于在 Core Data 中保存 UIImage 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Documents 文件夹中保存 UIImagePicker 中的 UIImage 并获取路径字符串以保存在 Swift 中的 Core Data 中

Core Data 不会从内存中释放 UIImage 数据 (ImageIO_PNG_Data)

Core Data iphone调试指针

Core-Data:如何在一个关系中保存一个对象两次

iPhone在Core Data中保存多个对象?

如何在 Core Data 中正确保存?