我应该如何在我的核心数据数据库中存储UIImages?

Asa*_*han 33 iphone core-data objective-c ios

我正在开发一个应用程序,需要大约100个图像或更多图像以及其他相关信息预先插入到Core Data数据库中.

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

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

Bra*_*son 56

将图像存储在Core Data数据库中非常容易.您只需将图像属性标记为可转换图像属性并创建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];
}
Run Code Online (Sandbox Code Playgroud)

对于transformable属性,请将此子类的名称指定为Value Transformer Name.

然后,您可以为托管此image属性的实体创建NSManagedObject子类,并声明此image属性的属性:

@property(nonatomic, retain) UIImage *thumbnailImage;
Run Code Online (Sandbox Code Playgroud)

您可以从UIImages读取UIImages并将UIImages写入此属性,它们将与NSData透明地更改以存储在数据库中.

是否这样做取决于您的具体情况.较大的图像可能不应该以这种方式存储,或者至少应该存在于它们自己的实体中,以便在跟随它们之间的关系之前不将它们提取到存储器中.小缩略图图像可能很好地以这种方式放入您的数据库.

  • 现在只需对任何人进行检查即可:UIImage现在符合iOS 5中的NSCoding.如果你能够定位iOS 5及更高版本,你可以设置属性和Transformable并完成.您还可以选中"允许外部存储"以使更大的图像自动保存在Core Data存储之外. (51认同)

Bji*_*nse 11

如上所述的图像变换器的一个很好的例子是在iPhoneCoreDataRecipes演示应用程序中.


小智 9

Apple确实提供了一些关于BLOB的建议: 大数据对象(BLOB)

如果您的应用程序使用大型BLOB("二进制大对象",如图像和声音数据),则需要注意尽量减少开销."小","适度"和"大"的确切定义是流动的,取决于应用程序的用法.一个宽松的经验法则是,大小为千字节的对象是"适度"大小的,大小为兆字节的对象是"大"大小的.一些开发人员在数据库中使用10MB BLOB取得了良好的性能.另一方面,如果一个应用程序在一个表中有数百万行,那么即使128个字节也可能是一个"适度"大小的CLOB(字符大对象),需要将其标准化为一个单独的表.

通常,如果需要将BLOB存储在持久性存储中,则应使用SQLite存储.XML和二进制存储要求整个对象图驻留在内存中,并且存储写入是原子的(参见"持久存储功能"),这意味着它们不能有效地处理大型数据对象.SQLite可以扩展以处理极大的数据库.正确使用,SQLite为高达100GB的数据库提供了良好的性能,单行可以容纳1GB(尽管当然,无论存储库的效率如何,将1GB的数据读入内存都是一项昂贵的操作).

BLOB通常表示实体的属性 - 例如,照片可能是Employee实体的属性.对于小到中等大小的BLOB(和CLOB),您应该为数据创建一个单独的实体,并创建一个一对一的关系来代替该属性.例如,您可以创建Employee和Photograph实体,它们之间具有一对一的关系,其中Employee与Photograph之间的关系取代了Employee的photograph属性.这种模式最大化了对象错误的好处(参见"Faulting and Uniquing").只有在实际需要时才会检索任何给定的照片(如果遍历关系).

但是,如果您能够将BLOB作为资源存储在文件系统上,并保持与这些资源的链接(例如URL或路径),那就更好了.然后,您可以在必要时加载BLOB.