Во-первых, не храните изображения (или любые двоичные данные) в Базовых данных;особенно на iOS.Вы получите гораздо лучшую производительность, если будете хранить ее на диске, а затем хранить ссылку на местоположение файла в Core Data.
Во-вторых, ваш пример кода не показывает, как вы помещаете данные в Основные данные.Поэтому трудно предложить решение.
Обновление
Я не нашел простой ссылки на то, как это сделать, вот один из них:
Image Cache Pre iOS 5.0
Чтобы настроить кэш изображений на диске в среде, предшествующей iOS 5.0, сначала необходимо создать на своей сущности атрибут, который будет NSString
.В этом примере мы назовем этот атрибут imageFilename
.Как только это будет завершено, мы захотим создать подкласс NSManagedObject
для нашей сущности, чтобы мы могли реализовать вспомогательные методы:
@interface MyEntity : NSManagedObject
@property (nonatomic, retain) NSString *imageFilename;
@property (nonatomic, retain) NSImage *image;
@end
Мы позволим Core Data управлять imageFilename
, так как онопределяется в модели.Однако мы собираемся реализовать средства доступа для image
.
@implementation MyEntity
@dynamic imageFilename;
@synthesize image = _image;
- (void)setImage:(UIImage*)image
{
NSString *filename = [self imageFilename];
if (!filename) {
filename = [[NSProcessInfo processInfo] globallyUniqueString];
[self setImageFilename:filename];
}
[_image release];
_image = [image retain];
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
NSData *data = UIImagePNGRepresentation(image);
NSError *error = nil;
if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error]) {
NSLog(@"Failed to write image to disk: %@\n%@", [error localizedDescription], [error userInfo]);
return;
}
}
. -setImage:
сохранит образ на диск в каталог кеша (обратите внимание, что каталог кеша не резервируется и может быть удаленсистемой в случае нехватки места).Он выбирает случайное имя файла, если оно еще не было создано.
Путь намеренно не сохраняется, поскольку каталог песочницы приложения может измениться.Поэтому мы хотим сохранить только имя файла в Core Data и разрешить путь.
Мы также сохраняем в памяти ссылку на изображение, чтобы мы не ударяли по диску, если изображение запрашивается снова в течение жизненного цикла этого объекта.Это причина для @synthesize
, даже если мы реализуем средства доступа.
Обратите внимание, что мы сохраняем изображения на диске в формате PNG.Это может быть дорого (процедуры сжатия относительно медленны), но оно сохраняет изображение в универсальном формате, который может быть полезен.
- (UIImage*)image
{
if (_image) return _image;
NSString *filename = [self imageFilename];
if (!filename) return nil;
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
if (![[NSFileManager defaultFileManager] fileExistsAtPath:filePath]) return nil;
_image = [[UIImage alloc] initWithContentsOfFile:filePath];
return _image;
}
Реализация -image
в значительной степени обратная.Мы проверяем, есть ли у нас имя файла;разрешите полный путь и загрузите изображение в память, а затем верните его вызывающей стороне.
- (void)prepareForDeletion
{
[super prepareForDeletion];
NSString *filename = [self imageFilename];
if (!filename) return nil;
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
NSError *error = nil;
if (![[NSFileManager defaultFileManager] removeItemAtPath:filePath error:&error]) {
NSLog(@"Potential error removing on disk image: %@\n%@", [error localizedDescription], [error userInfo]);
}
}
Мы хотим, чтобы наш каталог кэша был как можно более чистым, чтобы не создавать ситуацию с нехваткой места.Поэтому, когда объект будет удален из Базовых данных, мы хотим удалить файл с диска.Фактическая ошибка, которая происходит во время удаления, для нас не является фатальной.Это может быть ошибка, поскольку файл уже удален или что-то еще.Нет никаких причин полностью завершать эту ошибку, но важно зарегистрировать ее.
- (void)willTurnIntoFault
{
[super willTurnIntoFault];
[_image release], _image = nil;
}
@end
Наконец, мы реализуем метод -willTurnIntoFault
, чтобы освободить ссылку в изображении в памяти наконец жизненного цикла этой сущности.
Кэш изображений iOS 5.0 +
- Создание двоичного атрибута для сущности.
- Включение «Сохранить во внешнем файле записи»"бит.
- Нет третьего шага