Meilleur entrainement? - Tableau / dictionnaire en tant qu'attribut d'entité de données de base [fermé]

176

Je suis nouveau sur Core Data. J'ai remarqué que les types de collection ne sont pas disponibles en tant que types d'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 composent une adresse comme la rue, la ville, etc. ne nécessite pas d'entité distincte et est plus commodément stocké sous forme de dictionnaire / tableau que d'attributs / champs séparés). Je vous remercie.

RunLoop
la source
6
Créer une entité avec des champs de chaîne pour l'adresse est probablement plus facile à utiliser qu'un dictionnaire où vous devez vous souvenir de vos clés ...
Daniel

Réponses:

247

Il n'y a pas de tableau ou de type de dictionnaire "natif" dans Core Data. Vous pouvez stocker un NSArrayou un NSDictionarycomme attribut transformable. Cela utilisera le NSCodingpour sérialiser le tableau ou le dictionnaire en un NSDataattribut (et le désérialiser de manière appropriée lors de l'accès). L'avantage de cette approche est qu'elle est facile. L'inconvénient est que vous ne pouvez pas interroger le tableau ou le dictionnaire (il est stocké en tant que 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 un magasin de données SQLite) juste pour lire ou modifier une petite partie de la collection.

L'alternative consiste à utiliser des relations Core Data to-many pour modéliser la sémantique du tableau ou de la collection de dictionnaires. Les tableaux sont plus faciles, commençons par là. Les relations Core Data to-many modélisent vraiment un ensemble, donc si vous avez besoin d'une fonctionnalité de type tableau, vous devez soit trier l'ensemble (l'utilisation d'une propriété extraite est un moyen pratique de le faire), soit ajouter un attribut d'index supplémentaire à l'entité qui stocke les éléments du tableau et gère les index vous-même. Si vous stockez un tableau homogène (toutes les entrées sont du même type), il est facile de modéliser la description d'entité pour les entités du tableau. Sinon, 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 à plusieurs avec un ensemble d'entités qui stocke une clé et une valeur. La clé et la valeur sont toutes deux analogues à l'entité d'élément du tableau, décrite ci-dessus. Il peut donc s'agir de types natifs (si vous les connaissez à l'avance), d'un attribut transformable ou d'une relation avec une instance d'une famille d'entités spécifiques au type.

Si tout cela semble un peu intimidant, c'est le cas. Il est difficile de regrouper des données arbitraires dans un cadre dépendant du schéma comme Core Data.

Pour les données structurées, comme 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 pour modéliser un dictionnaire, cela rend votre interface utilisateur plus facile (les liaisons "fonctionneront") et votre logique de validation, etc. beaucoup plus claire puisqu'une grande partie peut être gérée par Core Data.

Mettre à jour

Depuis OS X 10.7, Core Data inclut un type d'ensemble ordonné qui peut être utilisé à la place d'un tableau. Si vous pouvez cibler 10.7 ou une version ultérieure, c'est la meilleure solution pour les collections ordonnées (de type tableau).

Barry Wark
la source
Appuyé - confirmé ce que je pensais déjà mais je ne savais pas sur les attributs transformables
jkp
3
@pixelfreak L'utilisation de transformable dépend de la manière dont vous devez utiliser les éléments de la collection. Si vous avez besoin de les interroger, ou si vous voulez pouvoir charger paresseusement certains d'entre eux ou tous, un attribut transformable ne fonctionnera pas. Si vous n'avez pas besoin d'un chargement différé, que vous n'avez pas besoin d'interroger et que vous avez toujours besoin de tous les éléments ou aucun, un attribut transformable peut fonctionner pour vous (et est certainement facile à implémenter).
Barry Wark
3
Ce que Barry dit est décrit plus en détail dans le Guide de programmation des données de base, chapitre Attributs persistants non standard .
Palimondo
2
Une mise en garde concernant les ensembles ordonnés: ne les utilisez pas pour des relations à plusieurs avec plus de quelques milliers d'objets du côté plusieurs. Si vous le faites, l'enregistrement peut commencer à prendre tellement de temps qu'il bloque le thread.
Kirk van Gorkom
2
Je ne comprends pas le "nouvel ensemble commandé". Est-ce un attribut? Parce que je ne peux pas le voir dans le menu des types d'attributs.
Parcelle du
11

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

Mon entité ressemble à ceci:

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

Mon code de gestion du code de modèle d'objet (données de base) 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];

Les éléments clés ici sont donc:

  • 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é par Core Data.
Caleb
la source
Alors auriez-vous mis ce code dans AppointmentSearchResponse.m dans une méthode init?
Chicowitz