30 votes

Comment dois-je stocker des UIImages dans ma base de données Core Data?

Je développe une application qui exige environ 100 images ou peut-être plus à être pré-inséré dans la Base de Données de la base de données avec d'autres informations connexes.

Maintenant, je peux facilement ajouter d'autres données par le simple fait d'écrire quelques lignes de code, mais pour UIImages je ne suis pas sûr de comment le faire sans écrire beaucoup de code. Je me demandais: est-il de toute façon le faire facilement, ou si il n'y a pas quelle est la meilleure façon d'atteindre cet objectif avec le minimum d'effort.

Aussi, est-il possible de stocker des images dans une Base de Données de la base de données ou doit-on seulement d'enregistrer les adresses des images sur le système de fichiers local?

52voto

Brad Larson Points 122629

Stocker des images dans une Base de Données de la base de données est très facile à faire. Vous avez juste besoin de marquer votre image en tant qu'attribut d'un transformable l'un et de créer une sous-classe de NSValueTransformer. À l'intérieur de cette sous-classe, ajoutez le code suivant:

+ (Class)transformedValueClass 
{
    return [NSData class]; 
}

+ (BOOL)allowsReverseTransformation 
{
    return YES; 
}

- (id)transformedValue:(id)value 
{
    if (value == nil)
        return nil;

    // I pass in raw data when generating the image, save that directly to the database
    if ([value isKindOfClass:[NSData class]])
        return value;

    return UIImagePNGRepresentation((UIImage *)value);
}

- (id)reverseTransformedValue:(id)value
{
    return [UIImage imageWithData:(NSData *)value];
}

Pour votre transformables attribut, spécifiez la présente sous-classe du nom que la Valeur du Transformateur de Nom.

Vous pouvez ensuite créer un NSManagedObject sous-classe de l'entité hébergeant cette image de l'attribut et de déclarer une propriété de cette image de l'attribut:

@property(nonatomic, retain) UIImage *thumbnailImage;

Vous pouvez lire UIImages et écrire UIImages à cette propriété, et ils seront en toute transparence changé vers et à partir de NSData être stockées dans la base de données.

De savoir si ou de ne pas faire cela dépend de votre cas particulier. De grandes images ne devraient probablement pas être stockés de cette manière, ou du moins devrait l'être dans leur propre entité afin qu'ils ne sont pas récupérées en mémoire jusqu'à ce qu'une relation est suivie. De petites vignettes sont probablement bien de mettre dans votre base de données de cette façon.

9voto

Bjinse Points 616

Un bon exemple du transformateur d'image décrit ci-dessus se trouve dans l'application de démonstration iPhoneCoreDataRecipes.

7voto

Chris Gummer Points 2891

Apple fournit quelques conseils autour de Gouttes: Des Objets De Données Volumineux (Blob)

Si votre application utilise des grosses Gouttes ("Binary Large OBjects" comme l'image et le son de données), vous devez prendre soin afin de minimiser les frais généraux. La exact définition de "petit", "modeste", et "grand" est fluide et dépend d'un demande d'utilisation. Un lâche de la règle de le pouce est que les objets dans l'ordre de de kilo-octets taille d'un "modeste" de taille moyenne et ceux de l'ordre de mo sont "grands" de taille moyenne. Certains développeurs ont obtenu de bons performance avec 10 MO Gouttes dans un la base de données. D'autre part, si un l'application compte des millions de lignes dans un tableau, même 128 octets peuvent être un "modeste" de la taille d'CLOB (Character Large Objet) qui doit être normalisé dans une table distincte.

En général, si vous avez besoin de stocker des objets Blob dans un magasin permanent, vous devez utiliser un SQLite magasin. Le XML et binaire les magasins d'exiger que l'ensemble de l'objet graphique résident dans la mémoire, et de les stocker les écritures sont atomiques (voir "Persistante Magasin de Fonctionnalités"), ce qui signifie qu'ils ne pas faire face efficacement à grande des objets de données. SQLite peuvent s'adapter à la poignée de très grandes bases de données. Correctement utilisé, SQLite fournit une bonne les performances des bases de données jusqu'à 100 go, et une seule ligne peut contenir jusqu'à 1 GO (même si bien sûr la lecture de 1 go de les données en mémoire est cher opération peu importe le degré d'efficacité de la référentiel).

Une GOUTTE représente souvent un attribut d'une entité, par exemple une photographie peut-être un attribut d'un Employé de l'entité. Pour les petites, de taille modeste Les BLOBs (et CLOBs), vous devez créer un entité distincte pour les données et les créer une relation privilégiée en place de l'attribut. Par exemple, vous peut créer de l'Employé et de la Photographie les entités avec un one-to-one relation entre eux, où l' relation du Salarié à l' Photographie remplace l'Employé photographie de l'attribut. Ce modèle maximise les avantages de l'objet défaillant (voir "Défaillant et Uniquing"). Toute photographie est seulement récupéré si il est en fait si besoin (si la relation est traversée).

Il est préférable, cependant, si vous êtes en mesure pour stocker les objets Blob que les ressources sur système de fichiers, et de maintenir des liens (comme des adresses Url ou des chemins d'accès) à ceux les ressources. Vous pouvez ensuite charger un BLOB en tant que et lorsque cela est nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X