La migliore pratica? - Matrice / dizionario come attributo di entità dati di base [chiuso]


176

Sono nuovo di Core Data. Ho notato che i tipi di raccolta non sono disponibili come tipi di attributo e vorrei sapere quale sia il modo più efficiente di archiviare i dati di tipo array / dizionario come attributo (ad esempio gli elementi che compongono un indirizzo come via, città, ecc. non richiede un'entità separata ed è più convenientemente archiviato come dizionario / array rispetto a attributi / campi separati). Grazie.


6
Creare un'entità con campi stringa per l'indirizzo è probabilmente più facile da usare di un dizionario in cui devi ricordare le tue chiavi ...
Daniel,

Risposte:


247

Non esiste un array "nativo" o un tipo di dizionario in Core Data. È possibile memorizzare un NSArrayo un NSDictionarycome attributo trasformabile. In questo modo verrà NSCodingserializzato l'array o il dizionario su un NSDataattributo (e opportunamente deserializzato al momento dell'accesso). Il vantaggio di questo approccio è che è facile. Il rovescio della medaglia è che non è possibile eseguire una query nell'array o nel dizionario (è archiviato come BLOB nell'archivio dati) e se le raccolte sono grandi, potrebbe essere necessario spostare molti dati da / verso l'archivio dati (se è un archivio dati SQLite) solo per leggere o modificare una piccola parte della raccolta.

L'alternativa consiste nell'utilizzare i dati di base tra più relazioni per modellare la semantica della raccolta di array o dizionari. Le matrici sono più semplici, quindi cominciamo con quello. Le relazioni tra molti dati di base stanno davvero modellando un set, quindi se hai bisogno di funzionalità simili a array, devi ordinare il set (usare una proprietà recuperata è un modo conveniente per farlo) o aggiungere un attributo di indice extra all'entità che memorizza gli elementi dell'array e gestisce gli indici da soli. Se si memorizza un array omogeneo (tutte le voci sono dello stesso tipo), è facile modellare la descrizione dell'entità per le entità dell'array. In caso contrario, dovrai decidere se utilizzare un attributo trasformabile per archiviare i dati dell'articolo o creare una famiglia di entità articolo.

La modellazione di un dizionario richiederà probabilmente una relazione a molti con un insieme di entità che memorizza una chiave e un valore. Sia la chiave che il valore sono analoghi all'entità articolo per l'array, descritto sopra. Quindi potrebbero essere tipi nativi (se li conosci in anticipo), un attributo trasformabile o una relazione con un'istanza di una famiglia di entità specifiche del tipo.

Se tutto ciò suona un po 'scoraggiante, lo è. Trasformare i dati arbitrari in un framework dipendente dallo schema come Core Data è difficile.

Per i dati strutturati, come gli indirizzi, è quasi sempre più facile passare il tempo a modellare esplicitamente le entità (ad esempio un attributo per ogni parte dell'indirizzo). Oltre a evitare tutto il codice aggiuntivo per modellare un dizionario, questo semplifica l'interfaccia utente (i binding "funzionano") e la logica di convalida, ecc. Molto più chiara, poiché gran parte di essa può essere gestita da Core Data.

Aggiornare

A partire da OS X 10.7, Core Data include un tipo di set ordinato che può essere utilizzato al posto di un array. Se puoi scegliere come target 10.7 o versioni successive, questa è la soluzione migliore per raccolte ordinate (simili a array).


Secondo: confermato ciò che già pensavo, ma non sapevo degli attributi trasformabili.
jkp,

3
@pixelfreak L'utilizzo di trasformabile dipende da come è necessario utilizzare gli articoli nella raccolta. Se devi eseguire una query su di essi o se vuoi essere in grado di caricare pigramente alcuni o tutti, un attributo trasformabile non funzionerà. Se non è necessario un caricamento lento, non è necessario eseguire una query e sono sempre necessari tutti gli elementi o nessuno, un attributo trasformabile potrebbe funzionare per te (ed è certamente facile da implementare).
Barry Wark,

3
Ciò che Barry dice è descritto in maggior dettaglio nella Guida alla programmazione dei dati di base, capitolo Attributi persistenti non standard .
Palimondo,

2
Una nota di cautela riguardo agli insiemi ordinati: non usarli per troppe relazioni con più di un paio di migliaia di oggetti sui molti lati. In tal caso, il salvataggio può iniziare a richiedere così tanto tempo da bloccare il thread.
Kirk van Gorkom,

2
Non capisco il "nuovo set ordinato". È un attributo? Perché non riesco a vederlo nel menu del tipo di attributo.
Trama il

11

Ho avuto un problema simile. Nel mio caso, volevo mappare una serie di stringhe. Ho seguito il consiglio di Barry e finalmente l'ho fatto funzionare. Ecco come appare un po 'del codice (che si spera che chiarisca le cose per chiunque lo incontri) ...

La mia entità è simile a questa:

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

Il codice Gestisci codice modello oggetto (dati principali) è simile al seguente:

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

Quindi gli elementi chiave qui sono:

  • Sto usando un NSSet per il tipo di proprietà
  • Sto usando NSTransformableAttributeType come tipo di attributo nel modello a oggetti dati gestiti core.

Quindi avresti inserito questo codice in AppointmentSearchResponse.m all'interno di un metodo init?
Chicowitz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.