2009-10-22 13 views
4

J'ai un modèle de données qui contient plusieurs entités, chacune avec plusieurs attributs différents qui stockent des données d'image. Ce seront toutes de petites images et je dois les stocker dans le magasin persistant plutôt que dans des fichiers externes. Bien que je puisse simplement stocker les données d'image dans un attribut binaire ou transformable, il est fort probable que l'utilisateur spécifiera des images identiques pour deux ou plus de ces attributs, je préfère donc stocker une copie de chaque image unique plutôt que la duplication des données d'image. Je me suis trompé avec la création d'une entité "ImageBlob" pour stocker les données d'image et l'utilisation de relations pour le faire, mais je suis un débutant avec Core Data et il ne me semble pas immédiatement si c'est la bonne façon de aller. En particulier, comment gérer les situations suivantes?Stockage de données identiques de manière efficace dans un modèle de données Core Data

  • Je veux tous mes attributs d'image dans plusieurs entités d'utiliser le même « banque de données d'image » de sorte que seule une instance de chaque blob d'image est stockée
  • je dois faire en sorte que si aucun objet utilisent un image dans le magasin de données qu'il est retiré

Quelle serait la meilleure façon de gérer cela?

Répondre

2

Ma première question serait de savoir comment vous prévoyez d'identifier lorsque deux objets utilisent la même image? Y a-t-il une propriété sur l'image que vous pouvez stocker et interroger pour déterminer si l'image que vous définissez existe déjà? Et comment cher, calcul, est-ce? Si cela prend beaucoup de temps, vous pourriez finir par optimiser le stockage et avoir un impact sur les performances. Cependant, si vous avez une manière de le faire efficacement, vous pouvez créer une entité ImageBlob pour faire ce que vous décrivez. L'entité qui utilise ImageBlob s doit avoir une relation imageBlob ou imageBlobs avec ImageBlob. ImageBlob doit avoir une relation inverse avec un nom comme, par exemple, users.

Dans votre code, lorsque vous souhaitez réutiliser un ImageBlob, il est aussi simple que de faire quelque chose comme ceci:

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 

Une autre considération que vous aurez envie de penser à ce qu'il faut faire avec blobs qui ne sont plus longtemps nécessaire. Vraisemblablement, vous voulez laisser tomber les images qui ne sont pas utilisées. Pour ce faire, vous pouvez enregistrer votre délégué d'application ou la sous-classe NSPersistentDocument (selon que votre application est basée sur un document ou non) pour la notification NSManagedObjectContextObjectsDidChangeNotification. Chaque fois que le contexte de l'objet géré change, vous pouvez supprimer des images inutiles comme ceci:

- (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

Merci, c'est une suggestion utile. Ce n'est pas une solution complète mais j'accepte la réponse. –

1

Vous pouvez ajouter une propriété unique appelée md5 à l'entité Image pour vous assurer que vous ne stocker les mêmes images une fois. En ce qui concerne les données de base, je pense que quelque chose comme cela pourrait fonctionner: Ensuite, faites une entité parente abstraite (Parent). Ajouter une relation de Parent à Image appelée image, et définir "Cascade" pour la méthode de suppression de sorte que lorsque vous supprimez Parent, Image est également supprimé.Ajouter une relation de Image à Parent appelée parent, ou autre, et définir "Nullify" pour la méthode de suppression afin que lorsque vous supprimez Image, l'image pour Parent est définie sur nil. Ensuite, ajoutez vos autres entités et définissez leur parent à Parent.

Questions connexes