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

176

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

RunLoop
источник
6
Создание сущности со строковыми полями для адреса, вероятно, проще в использовании, чем словарь, в котором вы должны помнить свои ключи ...
Даниил

Ответы:

247

В Базовых данных нет «родного» массива или типа словаря. Вы можете сохранить NSArrayили NSDictionaryкак трансформируемый атрибут. Это будет использовать NSCodingдля сериализации массива или словаря в NSDataатрибут (и соответственно десериализовать его при доступе). Преимущество такого подхода в том, что это легко. Недостатком является то, что вы не можете выполнять запросы в массив или словарь (он хранится как BLOB-объект в хранилище данных), и если коллекции большие, вам, возможно, придется перенести много данных в / из хранилища данных (если это хранилище данных SQLite) просто для чтения или изменения небольшой части коллекции.

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

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

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

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

Обновить

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

Барри Уарк
источник
Seconded - подтвердил то, что я уже думал, но я не знал о трансформируемых атрибутах.
JKP
3
@pixelfreak Использование трансформируемого зависит от того, как вам нужно использовать предметы в коллекции. Если вам нужно выполнить запрос к ним или вы хотите иметь возможность лениво загрузить некоторые или все из них, преобразуемый атрибут не будет работать. Если вам не нужна отложенная загрузка, не нужно запрашивать и всегда нужны все элементы или их нет, трансформируемый атрибут может работать для вас (и, конечно, его легко реализовать).
Барри Уарк
3
То, что говорит Барри, более подробно описано в Руководстве по программированию основных данных, глава Нестандартные постоянные атрибуты .
Палимондо
2
Предостережение относительно упорядоченных наборов: не используйте их для множества отношений с более чем несколькими тысячами объектов со многих сторон. Если вы это сделаете, сохранение может начаться так долго, что блокирует поток.
Кирк ван Горком
2
Я не понимаю о "новом заказанном наборе". Это атрибут? Потому что я не вижу его в меню типов атрибутов.
Сюжет
11

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

Моя сущность выглядит примерно так:

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

Мой код управления объектной моделью (базовые данные) выглядит примерно так:

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 в качестве типа атрибута в базовой модели управляемых объектов данных.
Калеб
источник
Так вы бы поместили этот код в AppointmentSearchResponse.m в методе init?
Чиковиц