2009-08-27 2 views
7

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

ответ

4

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

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

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

+0

hmmm ... interesting .. Я проверю это сейчас и вернусь к вам. Спасибо – RexOnRoids

+0

Я исправил проблему, но я до сих пор не знаю, какова была точная причина. Изображения, которые плавно масштабировались, имели размер 4kb, имели даже размеры (мощность 2) и были общими PNG-файлами, а изображения, которые масштабировались чоппильно, были размером 200kb +, неравномерными размерами и были PNG-файлами Adobe Fireworks. Как только я уменьшил размер файла, сравнил размеры, изменил тип файла, все начало плавно масштабироваться ... Кто знает, почему;) – RexOnRoids

1

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

8

Самый простой способ был бы 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 и более сложный механизм кэширования.

+0

Хорошее, простое решение. +1 – iPadDeveloper2011

+0

Определенно, спасибо. +1 –

9

Я сделал расширение ответа, предоставленного 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 
+0

Удивительный! Положив это на хорошее применение. :) –

+1

Вы не должны перезаписывать методы в категории. Просто используйте другое имя. См. Здесь: http://stackoverflow.com/a/5272612/921573 –

+0

Также я бы рекомендовал использовать 'NSCache' вместо' NSMutableDictionary'. Это именно так. –

 Смежные вопросы

  • Нет связанных вопросов^_^