Question

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 sont 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 au moins deux de ces attributs. Je préférerais donc stocker une copie de chaque image unique plutôt que dupliquer les données d'image.

J'ai eu du mal à créer un " ImageBlob " entité pour stocker les données d’image et utiliser des relations pour le faire, mais je suis un débutant avec Core Data et il ne m’apparaît pas immédiatement si c’est la bonne façon de procéder. En particulier, comment puis-je gérer les situations suivantes?

  • Je souhaite que tous les attributs d'image de plusieurs entités utilisent le même "magasin de données d'image". de sorte qu'une seule instance de chaque image blob soit stockée
  • Je dois m'assurer que si aucun objet n'utilise une image du magasin de données, elle sera supprimée

Quel serait le meilleur moyen de gérer cela?

Était-ce utile?

La solution

Ma première question serait de savoir comment comptez-vous identifier lorsque deux objets utilisent la même image? Existe-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 combien cela coûte-t-il, en termes de calcul? Si cela prend beaucoup de temps, vous risquez d’optimiser votre stockage et d’affecter vos performances.

Toutefois, si vous avez le moyen de le faire efficacement, vous pouvez créer une entité ImageBlob pour faire ce que vous décrivez. L'entité qui utilise ImageBlob doit avoir une relation imageBlob ou imageBlobs avec ImageBlob . ImageBlob doit avoir une relation inverse avec un nom tel que, par exemple, utilisateurs .

Dans votre code, lorsque vous souhaitez réutiliser un ImageBlob , il vous suffit 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 à prendre en compte est de savoir quoi faire avec les blobs qui ne sont plus nécessaires. Vraisemblablement, vous voulez supprimer toutes les images qui ne sont pas utilisées. Pour ce faire, vous pouvez inscrire votre délégué à l'application ou la sous-classe NSPersistentDocument (selon que votre application repose sur un document ou non) pour la notification NSManagedObjectContextObjectsDidChangeNotification . Chaque fois que le contexte de l'objet géré change, vous pouvez supprimer les images inutiles, comme suit:

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

Autres conseils

Vous pouvez ajouter une propriété unique appelée md5 à l'entité Image pour vous assurer que vous ne stockez qu'une seule fois les mêmes images.

En ce qui concerne les données de base, je pense que quelque chose comme ceci pourrait fonctionner: Créez ensuite une entité parent abstraite ( Parent ). Ajoutez une relation de Parent à Image appelée image et définissez " Cascade " pour la méthode de suppression, de sorte que lorsque vous supprimez Parent , Image est également supprimé. Ajoutez une relation de Image à Parent appelé parent , ou autre, et définissez & NULLify " pour la méthode de suppression afin que, lorsque vous supprimez Image , l’image correspondant à Parent soit définie sur nil . Ajoutez ensuite vos autres entités et définissez leur parent sur Parent .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top