Beste Übung? - Array / Wörterbuch als Kerndatenentitätsattribut [geschlossen]

175

Ich bin neu bei Core Data. Ich habe festgestellt, dass Sammlungstypen nicht als Attributtypen verfügbar sind, und möchte wissen, wie Array- / Wörterbuchtypdaten am effizientesten als Attribut gespeichert werden können (z. B. die Elemente, aus denen eine Adresse wie Straße, Stadt usw. besteht) erfordern keine separate Entität und werden bequemer als Wörterbuch / Array gespeichert als separate Attribute / Felder). Danke dir.

RunLoop
quelle
6
Das Erstellen einer Entität mit Zeichenfolgenfeldern für die Adresse ist wahrscheinlich einfacher als ein Wörterbuch, in dem Sie sich Ihre Schlüssel merken müssen ...
Daniel

Antworten:

246

In Core Data gibt es keinen "nativen" Array- oder Wörterbuchtyp. Sie können ein NSArrayoder ein NSDictionaryals transformierbares Attribut speichern . Dies wird verwendet, NSCodingum das Array oder Wörterbuch zu einem NSDataAttribut zu serialisieren (und es beim Zugriff entsprechend zu deserialisieren). Der Vorteil dieses Ansatzes ist, dass es einfach ist. Der Nachteil ist, dass Sie das Array oder Wörterbuch nicht abfragen können (es ist als BLOB im Datenspeicher gespeichert). Wenn die Sammlungen groß sind, müssen Sie möglicherweise viele Daten in den / aus dem Datenspeicher verschieben (falls dies der Fall ist) ein SQLite-Datenspeicher), um nur einen kleinen Teil der Sammlung zu lesen oder zu ändern.

Die Alternative besteht darin, Kerndaten-zu-viele-Beziehungen zu verwenden, um die Semantik des Arrays oder der Wörterbuchsammlung zu modellieren. Arrays sind einfacher, also fangen wir damit an. Core-Data-to-Many-Beziehungen modellieren eine Menge wirklich. Wenn Sie also eine Array-ähnliche Funktionalität benötigen, müssen Sie entweder die Menge sortieren (eine bequeme Eigenschaft ist eine bequeme Methode, um dies zu tun) oder der Entität ein zusätzliches Indexattribut hinzufügen Dadurch werden die Array-Elemente gespeichert und die Indizes selbst verwaltet. Wenn Sie ein homogenes Array speichern (alle Einträge sind vom gleichen Typ), ist es einfach, die Entitätsbeschreibung für die Array-Entitäten zu modellieren. Wenn nicht, müssen Sie entscheiden, ob Sie ein transformierbares Attribut zum Speichern der Artikeldaten verwenden oder eine Familie von Artikelentitäten erstellen möchten.

Das Modellieren eines Wörterbuchs erfordert wahrscheinlich eine zu viele Beziehungen zu einer Reihe von Entitäten, in denen ein Schlüssel und ein Wert gespeichert sind. Sowohl Schlüssel als auch Wert sind analog zu der oben beschriebenen Elemententität für das Array. Es kann sich also entweder um native Typen handeln (wenn Sie sie im Voraus kennen), um ein transformierbares Attribut oder um eine Beziehung zu einer Instanz aus einer Familie typspezifischer Entitäten.

Wenn das alles ein bisschen entmutigend klingt, ist es das auch. Es ist schwierig, beliebige Daten in ein schemaabhängiges Framework wie Core Data zu integrieren.

Bei strukturierten Daten wie Adressen ist es fast immer einfacher, die Zeit damit zu verbringen, die Entitäten explizit zu modellieren (z. B. ein Attribut für jeden Teil der Adresse). Dies vermeidet nicht nur den zusätzlichen Code zum Modellieren eines Wörterbuchs, sondern erleichtert auch Ihre Benutzeroberfläche (Bindungen funktionieren "nur") und Ihre Validierungslogik usw. viel klarer, da ein Großteil davon von Core Data verarbeitet werden kann.

Aktualisieren

Ab OS X 10.7 enthält Core Data einen geordneten Satztyp, der anstelle eines Arrays verwendet werden kann. Wenn Sie auf 10.7 oder höher abzielen können, ist dies die beste Lösung für geordnete (Array-ähnliche) Sammlungen.

Barry Wark
quelle
Abgeordnet - bestätigt, was ich bereits gedacht habe, aber ich wusste nichts über transformierbare Attribute.
JKP
3
@pixelfreak Die Verwendung von transformable hängt davon ab, wie Sie die Elemente in der Sammlung verwenden müssen. Wenn Sie Abfragen gegen sie durchführen müssen oder einige oder alle von ihnen träge laden möchten, funktioniert ein transformierbares Attribut nicht. Wenn Sie nicht verzögert laden müssen, nicht abfragen müssen und immer alle oder keine Elemente benötigen , kann ein transformierbares Attribut für Sie funktionieren (und ist sicherlich einfach zu implementieren).
Barry Wark
3
Was Barry sagt, wird ausführlicher im Core Data Programming Guide, Kapitel Nicht standardmäßige persistente Attribute, beschrieben .
Palimondo
2
Ein Hinweis zur Vorsicht bei geordneten Sets: Verwenden Sie sie nicht für zu viele Beziehungen mit mehr als ein paar tausend Objekten auf der vielen Seite. Wenn Sie dies tun, kann das Speichern so lange dauern, dass der Thread blockiert wird.
Kirk van Gorkom
2
Ich verstehe das "neu bestellte Set" nicht. Ist es ein Attribut? Weil ich es im Attributtyp-Menü nicht sehen kann.
Grundstück
11

Ich hatte ein ähnliches Problem. In meinem Fall wollte ich eine Reihe von Zeichenfolgen zuordnen. Ich folgte Barrys Rat und brachte es endlich zum Laufen. Hier ist, wie ein Teil des Codes aussieht (was hoffentlich die Dinge für alle anderen klären wird, die darauf stoßen) ...

Mein Wesen sieht ungefähr so ​​aus:

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

Mein Code zum Verwalten des Objektmodellcodes (Kerndaten) sieht ungefähr so ​​aus:

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

Die wichtigsten Punkte hier sind also:

  • Ich verwende ein NSSet für den Eigenschaftstyp
  • Ich verwende NSTransformableAttributeType als Attributtyp im Core Data Managed Object Model.
Caleb
quelle
Hätten Sie diesen Code also in AppointmentSearchResponse.m innerhalb einer init-Methode eingefügt?
Chicowitz