Эффективное хранение идентичных данных в модели данных Core Data

StackOverflow https://stackoverflow.com/questions/1605011

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

Однако, если у вас есть способ сделать это эффективно, вы могли бы создать ImageBlob сущность, чтобы делать то, что вы описываете.Объект , который использует ImageBlobs должен иметь 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];
    }
}

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top