Pregunta

Tengo un modelo de datos que contiene varias entidades, cada una con varios atributos diferentes que almacenan datos de imágenes. Todas serán imágenes pequeñas y necesito almacenarlas en la tienda persistente en lugar de como archivos externos.

Si bien puedo almacenar los datos de la imagen en un atributo Binario o Transformable, es muy probable que el usuario especifique imágenes idénticas para dos o más de estos atributos, por lo que prefiero almacenar una copia de cada imagen única en lugar de duplicando los datos de la imagen.

Me he equivocado creando un " ImageBlob " entidad para almacenar los datos de la imagen y el uso de relaciones para hacer esto, pero soy un novato con Core Data y no es inmediatamente evidente para mí si este es el camino correcto. En particular, ¿cómo trato las siguientes situaciones?

  • Quiero que todos mis atributos de imagen en varias entidades utilicen el mismo " almacén de datos de imagen " para que solo se almacene una instancia de cada blob de imágenes
  • Necesito asegurarme de que si ningún objeto está usando una imagen en el almacén de datos, se elimine

¿Cuál sería la mejor manera de manejar esto?

¿Fue útil?

Solución

Mi primera pregunta sería ¿cómo planea identificar cuándo dos objetos están usando la misma imagen? ¿Hay una propiedad en la imagen que puede almacenar y consultar para determinar si la imagen que está configurando ya existe? ¿Y qué tan caro, computacionalmente, es eso? Si lleva mucho tiempo, puede terminar optimizando el almacenamiento y afectando el rendimiento.

Sin embargo, si tiene una manera de hacerlo de manera eficiente, puede crear una entidad ImageBlob para hacer lo que describe. La entidad que utiliza ImageBlob s debe tener una relación imageBlob o imageBlobs con ImageBlob . ImageBlob debe tener una relación inversa con un nombre como, por ejemplo, usuarios .

En su código, cuando desea reutilizar un ImageBlob , es tan simple como hacer algo como esto:

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

Otra consideración en la que querrás pensar es qué hacer con los blobs que ya no son necesarios. Presumiblemente, desea eliminar cualquier imagen que no se esté utilizando. Para hacer esto, puede registrar su delegado de aplicación o la subclase NSPersistentDocument (dependiendo de si su aplicación está basada en documentos o no) para la notificación NSManagedObjectContextObjectsDidChangeNotification . Siempre que cambie el contexto del objeto gestionado, puede eliminar cualquier imagen innecesaria como esta:

- (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];
    }
}

Otros consejos

Puede agregar una propiedad única llamada md5 a la entidad Image para asegurarse de que solo está almacenando las mismas imágenes una vez.

En cuanto a las cosas de Core Data, creo que algo como esto podría funcionar: Luego, haga una entidad padre abstracta ( Parent ). Agregue una relación de Parent a Image llamada image , y establezca " Cascade " para el método de eliminación para que cuando elimine Parent , Image también se elimine. Agregue una relación de Image a Parent llamada parent , o lo que sea, y establezca " Nullify " para el método de eliminación para que cuando elimine Image , la imagen para Parent se establezca en nil . Luego, agregue sus otras entidades y establezca su padre en Parent .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top