核心数据 - 存储图片(iPhone)

47

我有一个应用程序,允许用户为他们的账户添加图片。

我想知道如何使用Core Data存储图像(从相机或照片库获取),因为我可能会为用户提供备份功能,并希望将图像数据传输到服务器。

我看到了一种设计建议,即创建一个Image模型对象,并与User模型对象创建1对1关系(这样只有在需要时才调用相关的Image对象)。但是,我不确定如何实际存储图像以及这是否在性能方面具有潜在的致命问题。

如果有任何尝试过此操作的人能给出方法和注意事项,我将不胜感激。

4个回答

84

在 Core Data 中存储图像数据的规则如下:

  • 小于 100 KB 就存储在相关实体(人员、地址等)中。
  • 小于 1 MB 就存储在与该实体有关系的另一个实体中,以避免性能问题。
  • 大于等于 1 MB 的数据需要存储在磁盘上,并在 Core Data 存储中引用其路径。

您可以使用 transformable 数据类型直接将 NSImage 存储到 Core Data 中。实际上,您可以使用 transformable 数据类型存储任何实现 NSCoder 协议的内容。

就个人而言,我不会将其转换为 CGImageRef,因为这样可能会丢失很多信息。


2
有一些令人兴奋的新方法可以在iOS5中帮助您摆脱这种麻烦。请查看文档,它仍然受NDA保护。 - steipete
8
@steipete现在iOS5不再受NDA的限制,我想你指的是新的"...attribute values for external storage". 如果您指定可以将托管对象属性的值存储为外部记录,则Core Data会根据每个值自动决定是否直接保存数据到数据库,还是将URI存储到它为您管理的单独文件中。 - Richard Venable
2
请注意,iOS 不支持外部存储。这是一个仅适用于桌面的标志。 - Marcus S. Zarra
2
我一直在一个小应用程序中使用外部存储标志,看起来一切都很正常,但是根据马库斯的说法,它似乎没有起到作用。我猜这意味着我保存的照片只是作为大块数据保存在我的数据库中。我希望苹果能告诉我这个! - Richard Venable
3
这是文档中的一个小注释,当我发现它时也让我感到震惊。 - Marcus S. Zarra
显示剩余6条评论

30

虽然这个问题已经被提出了一段时间,但我想分享一下关于这个问题的经验。


如果您要存储数量不受限制的图像,则不建议将它们存储在数据库中。您应该记住,有一天您会添加数据模型的新版本,并且您将不得不在应用程序更新时从旧的数据库迁移到新的数据库。这需要时间。数据库文件越大,迁移所需的时间就越长。

如果您想在数据库中存储图像,请确保不要在UIApplicationDelegateapplication: didFinishLaunchingWithOptions:方法中添加持久性存储。如果迁移没有在XX秒内完成,iOS将终止您的应用程序。


1
非常感谢您的评论,+1! - PeterK
你能否提供一个可靠的来源引用,证明你所说的“如果迁移在30秒内无法完成,iOS将终止你的应用程序”? - Pavan

4
注意事项:您可能会遇到巨大且难以处理的SQLite数据库。您真的希望用户一次上传几MB的文件到服务器吗?如果蜂窝连接中断几秒钟怎么办?
我认为最好使用Core Data来管理您的图像及其上传状态(已上传:是或否)。这样,您可以在应用程序工作流程适合的时候上传图像。好吧,由于有许多连接,这可能需要更长时间。但我认为这是一种更清晰的方法...
当谈到备份时,请考虑iTunes:无论如何都会同步本地iPhone“文档”文件夹。

谢谢您的答复。我可能会选择简单地将路径存储为字符串,然后依靠iTunes提供图像文件的备份(同时将其他与账户相关的数据存储在远程服务器上)。 - Urizen

3
您需要拥有一个 a a a,然后您可以像这样做:
CGImageRef imageRef = uiImage.CGImage;
CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef);
NSData *imageData = (NSData*)CGDataProviderCopyData(dataProvider);
[managedObject setValue:imageData forKey:@"data"];

在这里,managedObject是你的核心数据图像对象,@"data"是二进制属性的名称。您可能还需要保存图像格式以便稍后反序列化图像。

另一种选择是将图像保存到磁盘中并将路径存储在核心数据中。


当你完成时,也请释放imageData。 - Elfred
还可以查看使用可转换属性的方法:http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html - Nimrod
抱歉,我知道这可能看起来是一个基本的问题,但怎样才能保存图像格式(以及它的意思)?我以前从未遇到这个概念。 - Urizen
我指的是存储图像是jpg或png(或其他格式)这一事实。当您从数据库中获取图像数据以选择正确的数据提供程序将其转换为CGImageRef时,您将需要此信息。 - Elfred

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接