Najlepsze praktyki? - Tablica / słownik jako podstawowy atrybut jednostki danych [zamknięte]

176

Jestem nowy w Core Data. Zauważyłem, że typy kolekcji nie są dostępne jako typy atrybutów i chciałbym wiedzieć, jaki jest najbardziej efektywny sposób przechowywania danych typu tablica / słownik jako atrybutu (np. Elementy składające się na adres, takie jak ulica, miasto itp. nie wymaga oddzielnej jednostki i jest wygodniej przechowywany jako słownik / tablica niż oddzielne atrybuty / pola). Dziękuję Ci.

RunLoop
źródło
6
Utworzenie encji z polami tekstowymi na adres jest prawdopodobnie łatwiejsze w użyciu niż słownik, w którym musisz zapamiętać klucze ...
Daniel

Odpowiedzi:

247

W Core Data nie ma „rodzimej” tablicy ani typu słownika. Możesz przechowywać atrybut NSArraylub an NSDictionaryjako atrybut podlegający transformacji. Spowoduje to użycie NSCodingdo serializacji tablicy lub słownika do NSDataatrybutu (i odpowiedniej deserializacji po uzyskaniu dostępu). Zaletą tego podejścia jest to, że jest to łatwe. Wadą jest to, że nie możesz wykonywać zapytań do tablicy lub słownika (jest przechowywany jako BLOB w magazynie danych) i jeśli zbiory są duże, być może będziesz musiał przenieść wiele danych do / z magazynu danych (jeśli jest magazyn danych SQLite), aby odczytać lub zmodyfikować niewielką część kolekcji.

Alternatywą jest użycie relacji Core Data do wielu w celu modelowania semantyki kolekcji tablicy lub słownika. Tablice są łatwiejsze, więc zacznijmy od tego. Relacje Core Data to-many w rzeczywistości modelują zestaw, więc jeśli potrzebujesz funkcji przypominającej tablicę, musisz albo posortować zestaw (użycie właściwości pobranej jest wygodnym sposobem, aby to zrobić) lub dodać dodatkowy atrybut indeksu do encji który przechowuje elementy tablicy i samodzielnie zarządza indeksami. Jeśli przechowujesz jednorodną tablicę (wszystkie wpisy są tego samego typu), łatwo jest modelować opis jednostki dla jednostek tablicy. Jeśli nie, będziesz musiał zdecydować, czy użyć przekształcalnego atrybutu do przechowywania danych pozycji, czy też utworzyć rodzinę jednostek pozycji.

Modelowanie słownika będzie prawdopodobnie wymagało relacji to-many z zestawem jednostek, które przechowują klucz i wartość. Zarówno klucz, jak i wartość są analogiczne do jednostki pozycji dla tablicy, opisanej powyżej. Mogą więc być typami natywnymi (jeśli znasz je z wyprzedzeniem), atrybutem podlegającym transformacji lub relacją do instancji z rodziny jednostek specyficznych dla typu.

Jeśli to wszystko brzmi trochę zniechęcająco, to tak. Przetwarzanie dowolnych danych do struktury zależnej od schematu, takiej jak Core Data, jest trudne.

W przypadku danych strukturalnych, takich jak adresy, prawie zawsze łatwiej jest poświęcić czas na jawne modelowanie jednostek (np. Atrybut dla każdej części adresu). Oprócz unikania całego dodatkowego kodu do modelowania słownika, sprawia to, że interfejs użytkownika jest łatwiejszy (powiązania „po prostu działają”), a logika walidacji itp. Jest znacznie bardziej przejrzysta, ponieważ większość z nich może być obsługiwana przez Core Data.

Aktualizacja

Począwszy od systemu OS X 10.7, dane podstawowe zawierają uporządkowany typ zestawu, którego można użyć zamiast tablicy. Jeśli możesz kierować reklamy na wersję 10.7 lub nowszą, jest to najlepsze rozwiązanie dla uporządkowanych (przypominających tablicę) kolekcji.

Barry Wark
źródło
Oddelegowany - potwierdził to, co już myślałem, ale nie wiedziałem o atrybutach podlegających transformacji.
jkp
3
@pixelfreak Użycie transformable zależy od tego , jak potrzebujesz użyć elementów w kolekcji. Jeśli potrzebujesz zapytać o nie lub chcesz móc leniwie załadować niektóre lub wszystkie z nich, atrybut transformowalny nie zadziała. Jeśli nie potrzebujesz leniwego ładowania, nie musisz wykonywać zapytań i zawsze potrzebujesz wszystkich elementów lub żadnego, atrybut transformowalny może działać dla Ciebie (iz pewnością jest łatwy do zaimplementowania).
Barry Wark
3
To, co mówi Barry, jest opisane bardziej szczegółowo w Przewodniku programowania podstawowych danych, rozdział Niestandardowe trwałe atrybuty .
Palimondo
2
Uwaga dotycząca uporządkowanych zestawów: nie używaj ich do relacji zbyt wiele z więcej niż kilkoma tysiącami obiektów po wielu stronach. Jeśli to zrobisz, zapisywanie może zacząć trwać tak długo, że zablokuje wątek.
Kirk van Gorkom
2
Nie rozumiem „nowego zamówionego zestawu”. Czy to atrybut? Ponieważ nie widzę tego w menu typu atrybutu.
Działka
11

Miałem podobny problem. W moim przypadku chciałem zmapować tablicę ciągów. Postępowałem zgodnie z radą Barry'ego i wreszcie udało mi się to. Oto, jak wygląda część kodu (co, miejmy nadzieję, wyjaśni sprawę każdemu, kto na to wpadnie) ...

Moja jednostka wygląda mniej więcej tak:

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

Kod mojego Manage Object Model Code (Core Data) wygląda mniej więcej tak:

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

Oto kluczowe elementy:

  • Używam NSSet dla typu właściwości
  • Używam NSTransformableAttributeType jako typu atrybutu w modelu obiektów zarządzanych podstawowymi danymi.
caleb
źródło
Czy więc umieściłbyś ten kod wewnątrz AppointmentSearchResponse.m w ramach metody init?
Chicowitz,