Есть ли способ получить кэшированный UIImage из моего каталога «Документы»? - PullRequest
7 голосов
/ 27 августа 2009

Я знаю, что -imageNamed: метод возвращает Cached UIImage, но проблема в том, что мой файл изображения хранится в «Документах», а -imageNamed: метод, похоже, ищет только Bundle ... Я сейчас ( неохотно) используя -imageWithContentsOfFile: чтобы получить мое изображение из «Документов», но это не одно и то же ... Масштабирование UIImageView, содержащего полученное изображение, является изменчивым и неудобным. Масштабирование того же UIImageView, содержащего изображение, созданное с помощью -imageNamed: однако выглядит очень плавным. Итак, еще раз: Как я могу получить кэшированный UIImage из моих «Документов», если не могу использовать -imageNamed:?

Ответы [ 4 ]

9 голосов
/ 12 ноября 2010

Я сделал расширение ответа, предоставленного rpetrich, и переопределил метод imageName: чтобы добавить больше замены. Сначала он ищет основной пакет, а затем просматривает каталог caches. Конечно, вы можете изменить каталог кэшей на каталог документов.

@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
8 голосов
/ 27 августа 2009

Простейшим способом будет 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 подкласс и более сложный механизм кэширования потребуются, чтобы исправить это.

4 голосов
/ 27 августа 2009

Вы можете кэшировать UIImages себя так же, как -imageNamed:. Он просто загружает их, а затем держит их. Вы также можете удерживать их, используя NSDictionary и реализовать свой собственный -imageNamed:

Но меня больше беспокоит проблема с масштабированием. Как ваши изображения попадают в Документы, как вы масштабируете их, и тестировали ли вы один и тот же файл изображения, хранящийся в комплекте? Я сомневаюсь, что -imageNamed: имеет какое-либо отношение к этому. Я бы больше подозревал такие вещи, как тот факт, что к пакету применено некоторое сжатие (хотя у меня пока нет теории о том, почему это будет иметь значение на практике), различия в файле или различия в остальной части программы ведет себя во время масштабирования (вызывая конфликт на диске или процессоре). Кэширование вряд ли связано с этой проблемой.

Я бы сделал несколько профилей с инструментами, чтобы попытаться выяснить, откуда исходит хаотичность. Вы максимально используете диск, процессор, память? Что за узкое место?

1 голос
/ 27 августа 2009

А как насчет записи собственного кэша изображений? У вас есть все части на месте, теперь вам просто нужно инкапсулировать их и вести учет уже загруженных изображений.

...