2009-10-22 167 views
4

我有一个数据模型包含几个实体,每个实体都有几个不同的存储图像数据的属性。这些都将是小图像,我需要将它们存储在持久性存储中,而不是作为外部文件。在核心数据数据模型中有效地存储相同的数据

尽管我可以将图像数据存储在Binary或Transformable属性中,但很可能用户将为这些属性中的两个或多个指定相同的图像,所以我宁愿存储每个唯一图像的一个副本比复制图像数据。

我已经搞砸了创建一个“ImageBlob”实体来存储图像数据和使用关系来做到这一点,但我是一个新手与核心数据,它是不是立即明白,如果这是正确的方法走。特别是,我该如何处理以下情况?

  • 我想我所有的图像的多个实体的属性使用相同的“图像数据存储”,让各只有一个图像斑点的实例存储
  • 我需要确保,如果没有对象使用的是图像在数据存储中,它被删除

处理此问题的最佳方法是什么?

回答

2

我的第一个问题是如何计划确定两个物体何时使用相同的图像?您可以存储和查询图像上的属性,以确定您设置的图像是否已经存在?从计算上来说,这有多昂贵?如果花费很多时间,则可能会优化存储并影响性能。但是,如果您确实有办法有效地完成此操作,则可以创建一个ImageBlob实体来执行您所描述的操作。使用ImageBlob的实体应与ImageBlobimageBlobimageBlobs关系。 ImageBlob应该与名称相反,例如users

在你的代码,当你想重用ImageBlob,这是因为做这样的事情非常简单:

NSManagedObject *blob = // get the image blob 
NSManagedObject *user = // get the user 
[user setValue:blob forKey:@"imageBlob"]; // do this if it uses a single image 
[[user mutableSetValueForKey:@"imageBlobs"] addObject:blob]; // do this if it uses multiple images 

你要考虑的另一个考虑是如何处理那些没有斑点做需要更长时间据推测,你想删除任何未使用的图像。为此,您可以为NSManagedObjectContextObjectsDidChangeNotification通知注册您的应用程序委托或NSPersistentDocument子类(具体取决于您的应用程序是否基于文档)。每当管理对象环境的变化,你可以删除任何不需要的图像是这样的:

- (void)managedObjectContextObjectsDidSave:(NSNotification *)notification { 
    NSManagedObjectContext *managedObjectContext = [notification object]; 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    [fetchRequest setEntity:[NSEntity entityWithName:@"ImageBlob" inManagedObjectContext:managedObjectContext]]; 
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"[email protected] == 0"]; 
    NSArray *unusedBlobs = [managedObjectContext executeFetchRequest:fetchRequest error:nil]; // Don't be stupid like me; catch and handle the error 
    [fetchRequest release]; 

    for (NSManagedObject *blob in unusedBlobs) { 
     [managedObjectContext deleteObject:blob]; 
    } 
} 
+0

谢谢,这是一个有用的建议。这不是一个完整的解决方案,但我接受了答案。 – 2009-10-28 01:08:53

1

你可以一个名为MD5独特的属性添加到Image实体,以确保你只存储相同的图像一次。

至于核心数据的东西,我认为这样的事情可能会起作用: 然后,做一个抽象的父实体(Parent)。添加从ParentImage的关系,称为image,并为删除方法设置“级联”,以便删除Parent时,Image也被删除。将ImageParent之间的关系称为parent或其他内容,并为删除方法设置“Nullify”,以便在删除Image时,Parent的图像设置为nil。然后,添加您的其他实体并将其父项设置为Parent

相关问题