我应该如何将UIImage存储在我的Core Data数据库中?

我正在开发一个应用程序,需要大约100个图像或更多的预先插入核心数据数据库连同其他相关信息。

现在我可以通过写几行代码来轻松地添加其他数据,但是对于UIImage,我不确定如何在不编写大量代码的情况下执行此操作。 我想知道:无论如何,要做到这一点很简单,或者如果没有最好的方法来做到这一点,用最less的努力。

另外,将图像存储在Core Data数据库中还是可以的,或者我们应该只保存本地文件系统上的图像地址?

在Core Data数据库中存储图像很容易。 你只需要将你的图像属性标记为可变形的属性,并创build一个NSValueTransformer的子类。 在该子类中,添加如下所示的代码:

+ (Class)transformedValueClass { return [NSData class]; } + (BOOL)allowsReverseTransformation { return YES; } - (id)transformedValue:(id)value { if (value == nil) return nil; // I pass in raw data when generating the image, save that directly to the database if ([value isKindOfClass:[NSData class]]) return value; return UIImagePNGRepresentation((UIImage *)value); } - (id)reverseTransformedValue:(id)value { return [UIImage imageWithData:(NSData *)value]; } 

对于可变形属性,请将此子类的名称指定为值变换器名称。

然后,您可以为托pipe此图像属性的实体创build一个NSManagedObject子类,并为此图像属性声明一个属性:

 @property(nonatomic, retain) UIImage *thumbnailImage; 

你可以从这个属性中读取UIImage并写入UIImage,并且它们将被透明地改变到NSData中或者从NSData中被改变以存储在数据库中。

是否这样做取决于你的具体情况。 较大的图像可能不应该以这种方式存储,或者至less应该在自己的实体中,以便在跟随它们的关系之前,它们不会被带入内存中。 小缩略图图像可能很好地把你的数据库这种方式。

iPhoneCoreDataRecipes演示应用程序是上述图像转换器的一个很好的例子。

Apple提供了一些有关BLOB的build议: 大数据对象(BLOB)

如果您的应用程序使用大型BLOB(“二进制大型对象”,如图像和声音数据),则需要注意将开销降到最低。 “小”,“适度”和“大”的确切定义是stream畅的,取决于应用程序的用法。 一个宽松的经验法则是,大小为千字节的对象大小适中,而大小为兆字节大小的对象大小适中。 一些开发人员在数据库中使用10MB的BLOBs取得了良好的性能。 另一方面,如果一个应用程序在表中有数百万行,甚至128个字节可能是一个“适度”大小的CLOB(字符大的对象),需要被归一化到一个单独的表中。

通常,如果您需要将BLOB存储在持久性存储中,则应该使用SQLite存储。 XML和二进制存储需要整个对象图驻留在内存中,而存储写入是primefaces的(请参阅“持久存储特性”),这意味着它们不能有效地处理大型数据对象。 SQLite可以扩展来处理超大型的数据库。 正确使用,SQLite为高达100GB的数据库提供了良好的性能,单行最多可以容纳1GB(尽pipe读取1GB数据到内存中是一个昂贵的操作,无论存储库有多高效)。

BLOB通常表示实体的属性 – 例如,照片可能是Employee实体的属性。 对于小到中等大小的BLOB(和CLOB),应该为数据创build一个单独的实体,并创build一对一的关系来代替该属性。 例如,您可以使用它们之间的一对一关系创build员工和照片实体,从员工到照片的关系将replace员工的照片属性。 这种模式最大限度地提高了对象断层的好处(参见“断层和断层”)。 任何给定的照片只有在实际需要的情况下才能被检索(如果关系被遍历)。

但是,如果您能够将BLOBs作为资源存储在文件系统中,并维护这些资源的链接(如URL或path),则更好。 然后,您可以根据需要加载BLOB。