Я новичок в Core Data. Я заметил, что типы коллекций недоступны в качестве типов атрибутов, и хотел бы знать, какой наиболее эффективный способ хранения данных типа массива/словаря в качестве атрибута (например, элементы, составляющие адрес, такие как улица, город и т. д.). не требует отдельного объекта и удобнее хранится в виде словаря/массива, чем отдельные атрибуты/поля). Спасибо.
Лучшая практика? - Массив/словарь в качестве основного атрибута объекта данных
Ответы (2)
В Core Data нет «родного» массива или типа словаря. Вы можете сохранить NSArray
или NSDictionary
в качестве трансформируемого атрибута. Это будет использовать NSCoding
для сериализации массива или словаря в атрибут NSData
(и соответствующим образом десериализовать его при доступе). Преимущество этого подхода в том, что он прост. Недостатком является то, что вы не можете выполнять запросы к массиву или словарю (он хранится в виде BLOB в хранилище данных), и если коллекции большие, вам, возможно, придется перемещать много данных в/из хранилища данных (если оно хранилище данных SQLite) просто для чтения или изменения небольшой части коллекции.
Альтернативой является использование отношений Core Data to-many для моделирования семантики массива или коллекции словарей. Массивы проще, так что давайте начнем с них. Отношения Core Data-to-many на самом деле моделируют набор, поэтому, если вам нужна функциональность, подобная массиву, вы должны либо отсортировать набор (удобным способом сделать это, используя выбранное свойство), либо добавить дополнительный атрибут индекса к объекту. который хранит элементы массива и самостоятельно управляет индексами. Если вы храните однородный массив (все записи одного типа), легко смоделировать описание сущности для сущностей массива. Если нет, вам придется решить, использовать ли преобразуемый атрибут для хранения данных элемента или создать семейство сущностей элемента.
Моделирование словаря, скорее всего, потребует отношения «ко многим» к набору сущностей, в котором хранятся ключ и значение. И ключ, и значение аналогичны сущности элемента для массива, описанной выше. Таким образом, они могут быть либо собственными типами (если вы знаете их заранее), трансформируемым атрибутом или отношением к экземпляру из семейства сущностей, специфичных для типа.
Если все это звучит немного пугающе, так оно и есть. Втиснуть произвольные данные в зависимую от схемы структуру, такую как Core Data, непросто.
Для структурированных данных, таких как адреса, почти всегда проще потратить время на явное моделирование объектов (например, атрибут для каждой части адреса). Помимо того, что вы избегаете всего лишнего кода для моделирования словаря, это упрощает ваш пользовательский интерфейс (привязки будут «просто работать»), а вашу логику проверки и т. Д. Гораздо понятнее, поскольку большая часть этого может быть обработана Core Data.
Обновить
Начиная с OS X 10.7, Core Data включает тип упорядоченного набора, который можно использовать вместо массива. Если вы можете ориентироваться на 10.7 или более позднюю версию, это лучшее решение для упорядоченных (массивных) коллекций.
У меня была аналогичная проблема. В моем случае я хотел отобразить массив строк. Я последовал совету Барри и, наконец, заработал. Вот как выглядит часть кода (который, надеюсь, прояснит ситуацию для всех, кто столкнется с этим)...
Моя сущность выглядит примерно так:
@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 в качестве типа атрибута в объектной модели Core Data Managed Object Model.