Я знаю, что метод -imageNamed: возвращает Cached UIImage, но проблема в том, что мой файл изображения хранится в «Documents», а метод -imageNamed: похоже, только ищет Bundle ... Я в настоящее время (неохотно) с использованием -imageWithContentsOfFile: чтобы получить изображение из «Документов», но это не то же самое ... Масштабирование вверх/вниз UIImageView, содержащее результирующее изображение, изменчивое и неудобное. Масштабирование того же UIImageView, содержащего изображение, созданное с помощью -imageNamed: однако выглядит очень гладко. Итак, снова: Как я могу получить кешированный UIImage из моих «Документов», если я не могу использовать -imageNamed :?Любой способ получить Cached UIImage из моего каталога «Документы»?
ответ
Вы можете кэшировать UIImages
самостоятельно, как -imageNamed:
. Он просто загружает их, а затем держит на них. Вы можете использовать их также с помощью NSDictionary
и реализовать свои собственные -imageNamed:
Но меня больше беспокоит проблема, которую вы испытываете при масштабировании. Как ваши изображения попадают в документы, как вы их масштабируете, и проверили ли вы один и тот же файл изображения, хранящийся в комплекте? Я сомневаюсь, что -imageNamed:
имеет отношение к этому. Я бы более подозревал такие вещи, как тот факт, что пакет имеет некоторое сжатие, применяемое к нему (хотя у меня пока нет теории о том, почему это имеет значение на практике), различия в файле или различия в том, как остальная часть программы ведет себя во время масштабирования (вызывая конфликт на диске или CPU). Кэширование вряд ли связано с этой проблемой.
Я хотел бы сделать некоторые профилирование ж/инструменты, чтобы попытаться выяснить, где зыбь откуда. Вы максимизируете диск, процессор, память? В чем узкое место?
Как насчет написания собственного кеша изображения? У вас есть все части на месте, теперь вам просто нужно инкапсулировать его и сохранить запись изображений, которые вы уже загрузили.
Самый простой способ был бы NSMutableDictionary
хранения кэшированные изображения и четкий метод кэша:
@interface UIImage (CacheExtensions)
+ (id)cachedImageWithContentsOfFile:(NSString *)path;
+ (void)clearCache;
@end
static NSMutableDictionary *UIImageCache;
@implementation UIImage (CacheExtensions)
+ (id)cachedImageWithContentsOfFile:(NSString *)path
{
id result;
if (!UIImageCache)
UIImageCache = [[NSMutableDictionary alloc] init];
else {
result = [UIImageCache objectForKey:path];
if (result)
return result;
}
result = [UIImage imageWithContentsOfFile:path];
[UIImageCache setObject:result forKey:path];
return result;
}
+ (void)clearCache
{
[UIImageCache removeAllObjects];
}
@end
Примечание: вы должны вызвать +[UIImage clearCache]
из метода didReceiveMemoryWarning
. Кроме того, clearCache
аннулирует все объекты в кеше, а не только неиспользуемые элементы; для устранения этого потребуются подклассы UIImage
и более сложный механизм кэширования.
Хорошее, простое решение. +1 – iPadDeveloper2011
Определенно, спасибо. +1 –
Я сделал расширение ответа, предоставленного rpetrich, и переопределить imageName: метод добавить больше замены. Сначала он ищет основной пакет, а затем просматривает каталог кэшей. Разумеется, вы можете изменить каталог кэшей в каталоге документов.
@interface UIImage (CacheExtensions)
+ (UIImage *)imageNamed:(NSString *)name;
+ (void)clearCache;
@end
#import "UIImage+CacheExtensions.h"
static NSMutableDictionary *UIImageCache;
@implementation UIImage (CacheExtensions)
+ (UIImage *)imageNamed:(NSString *)name
{
id result;
if (!UIImageCache)
UIImageCache = [[NSMutableDictionary alloc] init];
else {
result = [UIImageCache objectForKey:name];
if (result) return result;
}
// First, check the main bundle for the image
NSString *imagePath = [[NSBundle mainBundle] pathForResource:name ofType:nil];
result = [UIImage imageWithContentsOfFileimagePath];
if(result) {
[UIImageCache setObject:result forKey:name];
return result;
}
// If not found, search for the image in the caches directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesImagePath = [[paths lastObject] stringByAppendingPathComponent:name];
result = [UIImage imageWithContentsOfFile:cachesImagePath];
if(result) {
[UIImageCache setObject:result forKey:name];
return result;
}
return nil;
}
+ (void)clearCache
{
[UIImageCache removeAllObjects];
}
@end
Удивительный! Положив это на хорошее применение. :) –
Вы не должны перезаписывать методы в категории. Просто используйте другое имя. См. Здесь: http://stackoverflow.com/a/5272612/921573 –
Также я бы рекомендовал использовать 'NSCache' вместо' NSMutableDictionary'. Это именно так. –
hmmm ... interesting .. Я проверю это сейчас и вернусь к вам. Спасибо – RexOnRoids
Я исправил проблему, но я до сих пор не знаю, какова была точная причина. Изображения, которые плавно масштабировались, имели размер 4kb, имели даже размеры (мощность 2) и были общими PNG-файлами, а изображения, которые масштабировались чоппильно, были размером 200kb +, неравномерными размерами и были PNG-файлами Adobe Fireworks. Как только я уменьшил размер файла, сравнил размеры, изменил тип файла, все начало плавно масштабироваться ... Кто знает, почему;) – RexOnRoids