Эффективное хранение идентичных данных в модели данных Core Data - PullRequest
4 голосов
/ 22 октября 2009

У меня есть модель данных, которая содержит несколько объектов, каждый из которых имеет несколько различных атрибутов, которые хранят данные изображения. Все это будут небольшие изображения, и мне нужно хранить их в постоянном хранилище, а не в виде внешних файлов.

Хотя я могу просто сохранять данные изображения в двоичном или трансформируемом атрибуте, вполне вероятно, что пользователь будет указывать идентичные изображения для двух или более этих атрибутов, поэтому я бы предпочел хранить одну копию каждого уникального изображения, а не дублирование данных изображения.

Я возился с созданием сущности "ImageBlob" для хранения данных изображения и использованием связей, чтобы сделать это, но я новичок в Core Data, и мне не сразу понятно, правильный ли это путь , В частности, как мне справиться со следующими ситуациями?

  • Я хочу, чтобы все мои атрибуты изображения в нескольких объектах использовали одно и то же «хранилище данных изображения», чтобы сохранялся только один экземпляр каждого большого двоичного объекта изображения
  • Мне нужно убедиться, что если в хранилище данных нет объектов, использующих изображение, оно будет удалено

Каков наилучший способ справиться с этим?

Ответы [ 2 ]

2 голосов
/ 23 октября 2009

Мой первый вопрос: как вы планируете определить, когда два объекта используют одно и то же изображение? Есть ли свойство изображения, которое вы можете сохранить и запросить, чтобы определить, существует ли уже заданное изображение? И насколько это дорого в вычислительном отношении? Если это займет много времени, вы можете оптимизировать систему хранения и повлиять на производительность.

Однако, если у вас есть способ сделать это эффективно, вы можете создать ImageBlob сущность, чтобы сделать то, что вы описываете. Сущность, которая использует ImageBlob s, должна иметь отношение 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

Еще одно соображение, о котором вы захотите подумать, - что делать с каплями, которые больше не нужны. Предположительно, вы хотите удалить любые изображения, которые не используются. Для этого вы можете зарегистрировать своего делегата приложения или подкласс 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 голос
/ 07 сентября 2010

Вы можете добавить уникальное свойство md5 к объекту Image, чтобы убедиться, что вы сохраняете одни и те же изображения только один раз.

Что касается материала Core Data, я думаю, что-то вроде этого может работать: Затем создайте абстрактный родительский объект (Parent). Добавьте отношение от Parent до Image, называемое image, и задайте «Каскад» для метода удаления, чтобы при удалении Parent, Image также удалялось. Добавьте отношение от Image к Parent, называемое parent, или что-то еще, и установите «Nullify» для метода удаления, чтобы при удалении Image для Parent было установлено значение nil. Затем добавьте свои другие сущности и установите для их родителей значение Parent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...