Как я должен хранить UIImages в моей базе данных Core Data?
Я занимаюсь разработкой приложения, для которого требуется предварительно вставить около 100 или даже больше изображений в базу данных Core Data вместе с другой соответствующей информацией.
Теперь я могу легко добавить другие данные, просто написав несколько строк кода, но для UIImages я не уверен, как это сделать без написания большого количества кода. Мне было интересно: есть ли в любом случае это легко сделать, или нет лучшего способа добиться этого с наименьшими усилиями.
Кроме того, можно ли хранить изображения в базе данных Core Data или мы должны только сохранять адреса изображений только в локальной файловой системе?
3 ответа
Хранить изображения в базе данных Core Data довольно легко. Вам просто нужно пометить атрибут изображения как трансформируемый и создать подкласс NSValueTransformer. В этом подклассе добавьте код, подобный следующему:
+ (Class)transformedValueClass
{
return [NSData class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(id)value
{
if (value == nil)
return nil;
// I pass in raw data when generating the image, save that directly to the database
if ([value isKindOfClass:[NSData class]])
return value;
return UIImagePNGRepresentation((UIImage *)value);
}
- (id)reverseTransformedValue:(id)value
{
return [UIImage imageWithData:(NSData *)value];
}
Для вашего преобразуемого атрибута укажите имя этого подкласса как Имя преобразователя значения.
Затем можно создать подкласс NSManagedObject для объекта, на котором размещен этот атрибут изображения, и объявить свойство для этого атрибута изображения:
@property(nonatomic, retain) UIImage *thumbnailImage;
Вы можете читать UIImages из и записывать UIImages в это свойство, и они будут прозрачно изменены в и из NSData для хранения в базе данных.
То, стоит ли это делать, зависит от вашего конкретного случая. Большие изображения, вероятно, не должны храниться таким образом, или, по крайней мере, должны быть в их собственной сущности, чтобы они не извлекались в память до тех пор, пока не будут соблюдены отношения с ними. Небольшие миниатюрные изображения, вероятно, можно поместить в вашу базу данных таким образом.
Хорошим примером преобразователя изображения, как описано выше, является демонстрационное приложение iPhoneCoreDataRecipes.
Apple предоставляет несколько советов относительно больших двоичных объектов: большие объекты данных (большие двоичные объекты)
Если ваше приложение использует большие большие двоичные объекты ("большие двоичные объекты", такие как изображения и звуковые данные), необходимо позаботиться о том, чтобы минимизировать накладные расходы. Точное определение "маленький", "скромный" и "большой" является гибким и зависит от использования приложения. Эмпирическое правило гласит, что объекты размером порядка килобайт имеют "скромный" размер, а объекты размером порядка мегабайт - "большой". Некоторые разработчики достигли хорошей производительности с 10 МБ BLOB в базе данных. С другой стороны, если приложение имеет миллионы строк в таблице, даже 128 байтов могут быть CLOB "скромного" размера (крупный символьный объект), который необходимо нормализовать в отдельную таблицу.
В общем, если вам нужно хранить большие двоичные объекты в постоянном хранилище, вам следует использовать хранилище SQLite. Для хранения XML и двоичных файлов требуется, чтобы весь граф объектов находился в памяти, а записи в хранилище были атомарными (см. "Функции постоянного хранилища"), что означает, что они неэффективно работают с большими объектами данных. SQLite может масштабироваться для работы с очень большими базами данных. При правильном использовании SQLite обеспечивает хорошую производительность для баз данных объемом до 100 ГБ, а одна строка может содержать до 1 ГБ (хотя, конечно, чтение 1 ГБ данных в память является дорогостоящей операцией, независимо от того, насколько эффективен репозиторий).
BLOB часто представляет атрибут объекта - например, фотография может быть атрибутом объекта Employee. Для BLOB малого и среднего размера (и CLOB) необходимо создать отдельный объект для данных и создать отношение "один к одному" вместо атрибута. Например, вы можете создать сущности "Сотрудник" и "Фотография" с взаимно-однозначным отношением между ними, где отношение "Сотрудник" к "Фотография" заменяет атрибут фотографии сотрудника. Этот шаблон максимизирует преимущества повреждения объекта (см. "Неисправность и уникальность"). Любая данная фотография извлекается, только если она действительно необходима (если пересекаются отношения).
Однако лучше, если вы сможете хранить большие двоичные объекты как ресурсы в файловой системе и поддерживать ссылки (например, URL-адреса или пути) на эти ресурсы. Затем вы можете загрузить BLOB по мере необходимости.