Лучшая практика? - Массив/Словарь как основной атрибут объекта данных

Я новичок в Core Data. Я заметил, что типы коллекций недоступны в качестве типов атрибутов и хотели бы знать, что наиболее эффективным способом является сохранение данных типа массива/словаря в качестве атрибута (например, элементы, составляющие такой адрес, как улица, город и т.д.) не требуется отдельный объект и более удобно хранить в виде словаря/массива, чем отдельные атрибуты/поля). Спасибо.

Ответ 1

В Core Data нет "родного" массива или типа словаря. Вы можете сохранить NSArray или NSDictionary в качестве преобразуемого атрибута. Это будет использовать NSCoding для сериализации массива или словаря с атрибутом NSData (и соответствующим образом десериализовать его при доступе). Преимущество такого подхода заключается в том, что это легко. Недостатком является то, что вы не можете запрашивать в массиве или словаре (он хранится как BLOB в хранилище данных), и если коллекции большие, вам может потребоваться переместить много данных в/из хранилища данных (если это хранилище данных SQLite), просто чтобы прочитать или изменить небольшую часть коллекции.

Альтернативой является использование отношений Core Data to-many для моделирования семантики массива или коллекции словарей. Массивы проще, поэтому давайте начнем с этого. Соотношения Core Data to-many действительно моделируют набор, поэтому, если вам нужна подобная массиву функциональность, вам нужно либо отсортировать набор (используя свойство с привилегиями - это удобный способ сделать это), либо добавить дополнительный атрибут индекса для объекта который хранит элементы массива и самостоятельно управляет индексами. Если вы храните однородный массив (все записи одного типа), легко смоделировать описание объекта для объектов массива. В противном случае вам придется решить, использовать ли трансформируемый атрибут для хранения данных элемента или создания семейства объектов объектов.

Моделирование словаря, вероятно, потребует отношения to-many к набору сущностей, в котором хранится ключ и значение. Оба ключа и значение аналогичны объекту элемента для массива, описанному выше. Таким образом, они могут быть либо родными типами (если вы их заранее знаете), трансформируемым атрибутом или отношением к экземпляру из семейства объектов, специфичных для типа.

Если это все звучит немного сложнее, это так. Произвольные произвольные данные в структуре, зависящей от схемы, например Core Data, являются жесткими.

Для структурированных данных, таких как адреса, почти всегда проще тратить время на моделирование объектов явно (например, атрибут для каждой части адреса). Кроме того, чтобы избежать использования дополнительного кода для моделирования словаря, это упростит ваш интерфейс (привязки "работают" ), а ваша логика проверки и т.д. Намного понятнее, поскольку большая часть из них может обрабатываться Core Data.

Обновление

Начиная с OS X 10.7, Core Data включает упорядоченный тип набора, который можно использовать вместо массива. Если вы можете настроить таргетинг 10.7 или новее, это лучшее решение для упорядоченных (массивных) коллекций.

Ответ 2

У меня была аналогичная проблема. В моем случае я хотел отобразить массив строк. Я последовал совету Барри и, наконец, начал работать. Вот что выглядит код (который, надеюсь, прояснит ситуацию для всех, кто сталкивается с этим)...

My Entity выглядит примерно так:

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

Код кода My Manage Object Model Code (Core Data) выглядит примерно так:

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

Итак, ключевыми элементами здесь являются:

  • Я использую NSSet для типа свойства
  • Я использую NSTransformableAttributeType как тип атрибута в управляемой объектной модели Core Data.