web-dev-qa-db-fra.com

Meilleur entrainement? - Tableau / dictionnaire en tant qu'attribut d'entité de données principale

Je suis nouveau sur Core Data. J'ai remarqué que les types de collection ne sont pas disponibles en tant qu'attributs et j'aimerais savoir quel est le moyen le plus efficace de stocker des données de type tableau/dictionnaire en tant qu'attribut (par exemple, les éléments qui constituent une adresse comme une rue, une ville, etc. nécessite pas une entité séparée et est plus commodément stocké sous forme de dictionnaire/tableau que d'attributs/champs séparés). Merci.

174
RunLoop

Il n'y a pas de type de tableau ou de dictionnaire "natif" dans Core Data. Vous pouvez stocker un NSArray ou un NSDictionary en tant qu'attribut transformable. Ceci utilisera le NSCoding pour sérialiser le tableau ou le dictionnaire en un attribut NSData (et le désérialiser de manière appropriée lors de l'accès). L'avantage de cette approche est que c'est facile. L'inconvénient est que vous ne pouvez pas interroger dans le tableau ou le dictionnaire (il est stocké sous forme de BLOB dans le magasin de données) et si les collections sont volumineuses, vous devrez peut-être déplacer beaucoup de données vers/depuis le magasin de données (si c'est le cas). un magasin de données SQLite) pour lire ou modifier une petite partie de la collection.

L'alternative consiste à utiliser des relations entre plusieurs données principales pour modéliser la sémantique de la collection de tableaux ou de dictionnaires. Les tableaux sont plus faciles, alors commençons par ça. Les relations entre plusieurs données de base modélisent en réalité un ensemble. Par conséquent, si vous avez besoin de fonctionnalités similaires à celles d'un tableau, vous devez soit trier l'ensemble (l'utilisation d'une propriété extraite est un moyen pratique de le faire) ou ajouter un attribut d'index supplémentaire à l'entité. qui stocke les éléments du tableau et gère vous-même les index. Si vous stockez un tableau homogène (toutes les entrées sont du même type), il est facile de modéliser la description de l'entité pour les entités du tableau. Dans le cas contraire, vous devrez décider d'utiliser un attribut transformable pour stocker les données d'élément ou créer une famille d'entités d'élément.

La modélisation d'un dictionnaire nécessitera probablement une relation multiple avec un ensemble d'entités stockant une clé et une valeur. La clé et la valeur sont analogues à l'entité item du tableau, décrite ci-dessus. Ils peuvent donc être des types natifs (si vous les connaissez à l'avance), un attribut transformable ou une relation avec une instance à partir d'une famille d'entités spécifiques à un type.

Si tout cela semble un peu intimidant, c'est bien le cas. Traverser des données arbitraires dans un cadre dépendant du schéma tel que Core Data est difficile.

Pour les données structurées, telles que les adresses, il est presque toujours plus facile de passer du temps à modéliser explicitement les entités (par exemple, un attribut pour chaque partie de l'adresse). En plus d'éviter tout le code supplémentaire nécessaire à la modélisation d'un dictionnaire, cela simplifie votre interface utilisateur (les liaisons vont "fonctionner"), votre logique de validation, etc., de manière beaucoup plus claire, car une grande partie peut être gérée par Core Data.

Mise à jour

À partir de OS X 10.7, Core Data inclut un type de jeu ordonné pouvant être utilisé à la place d'un tableau. Si vous pouvez cibler 10.7 ou une version ultérieure, il s'agit de la meilleure solution pour les collections ordonnées (de type tableau).

244
Barry Wark

J'ai eu un problème similaire. Dans mon cas, je voulais mapper un tableau de chaînes. J'ai suivi le conseil de Barry et je l'ai finalement fait fonctionner. Voici à quoi ressemble le code (qui, espérons-le, clarifiera les choses à quiconque se heurtera à cela) ...

Mon entité ressemble à ceci:

@interface AppointmentSearchResponse : NSManagedObject
@property (nonatomic, retain) NSSet *messages;
@end

Mon code de code de modèle d'objet de gestion (Core Data) ressemble à ceci:

NSEntityDescription *entityDescription = [[NSEntityDescription alloc] init];
[entityDescription setName:@"AppointmentSearchResponse"];
[entityDescription setManagedObjectClassName:@"AppointmentSearchResponse"];

NSMutableArray *appointmentSearchResponseProperties = [NSMutableArray array];
NSAttributeDescription *messageType = [[NSAttributeDescription alloc] init];    
[messageType setName:@"messages"];
[messageType setAttributeType:NSTransformableAttributeType];
[appointmentSearchResponseProperties addObject:messageType];

[entityDescription setProperties:appointmentSearchResponseProperties];

Donc, les éléments clés ici sont:

  • J'utilise un NSSet pour le type de propriété
  • J'utilise NSTransformableAttributeType comme type d'attribut dans le modèle d'objet géré des données de base.
11
caleb