我有一个包含多个实体的数据模型,每个实体都有几个存储图像数据的不同属性。这些都是小图像,我需要将它们存储在持久存储中而不是外部文件中。
虽然我可以将图像数据存储在Binary或Transformable属性中,但用户很可能会为这些属性中的两个或更多属性指定相同的图像,所以我宁愿存储每个唯一图像的一个副本而不是复制图像数据。
我已经搞砸了创建一个“ImageBlob”实体来存储图像数据并使用关系来做到这一点,但我是Core Data的新手,如果这是正确的方法我不会立刻明白。特别是,我该如何处理以下情况?
处理此问题的最佳方法是什么?
答案 0 :(得分:2)
我的第一个问题是你打算如何确定两个对象何时使用相同的图像?您可以存储和查询图像上的属性,以确定您设置的图像是否已存在?计算上有多贵?如果需要花费大量时间,最终可能会优化存储并影响性能。
但是,如果您确实有办法有效地执行此操作,则可以创建一个ImageBlob
实体来执行您所描述的操作。使用ImageBlob
的实体应与imageBlob
建立imageBlobs
或ImageBlob
关系。 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
您需要考虑的另一个考虑因素是如何处理不再需要的blob。据推测,您想要删除任何未使用的图像。为此,您可以为NSPersistentDocument
通知注册您的应用程序委托或NSManagedObjectContextObjectsDidChangeNotification
子类(取决于您的应用程序是否基于文档)。每当托管对象上下文发生更改时,您都可以删除任何不需要的图像,如下所示:
- (void)managedObjectContextObjectsDidSave:(NSNotification *)notification {
NSManagedObjectContext *managedObjectContext = [notification object];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntity entityWithName:@"ImageBlob" inManagedObjectContext:managedObjectContext]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"users.@count == 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];
}
}
答案 1 :(得分:1)
您可以向Image
实体添加一个名为md5的唯一属性,以确保您只存储一次相同的图像。
至于核心数据的东西,我觉得这样的东西可能会起作用:
然后,创建一个抽象的父实体(Parent
)。添加从Parent
到名为Image
的{{1}}的关系,并为删除方法设置“级联”,这样当您删除image
时,Parent
也会被删除。添加从Image
到Image
的{{1}}或其他任何关系,并为删除方法设置“Nullify”,这样当您删除Parent
时,{{1}的图像1}}设置为parent
。然后,添加其他实体并将其父级设置为Image
。