時常需要從網路上抓取影像載入APP裡頭,尤其是在TableView的cell頻繁消失又出現的狀況,會不停地重複同樣(下載與顯示)的動作,這樣子做不是不行,然而使用者體驗會有點差,儘管已經用多執行緒去抓圖和載圖,操作上還算相當順暢,然而使用者還是會看到影像怎麼這時候消失變出現,接著又滾回去又從消失變出現,使用者體驗實在相當糟糕⋯⋯
於是想當然爾,我們會想要把已經載入的圖給暫存起來,下次要顯示時直接抓暫存在記憶體中的影像快取 (Image Cache)即可!
在iOS中,蘋果提供NSCache和NSDictionary很相似,利用key和value的方式存儲,不一樣的是NSCache在記憶體吃緊的時候會做自動釋放的動作。
檔案:ImageCache.h
#import <Foundation/Foundation.h> @interface ImageCache : NSObject @property (nonatomic, retain) NSCache *imgCache; #pragma mark - Methods + (ImageCache*)sharedImageCache; - (void) AddImage:(NSString *)imageURL :(UIImage *)image; - (UIImage*) GetImage:(NSString *)imageURL; - (BOOL) DoesExist:(NSString *)imageURL; @end
檔案:ImageCache.m
#import "ImageCache.h"
@implementation ImageCache
@synthesize imgCache;
#pragma mark - Methods
static ImageCache* sharedImageCache = nil;
+(ImageCache*)sharedImageCache
{
@synchronized([ImageCache class])
{
if (!sharedImageCache)
sharedImageCache= [[self alloc] init];
return sharedImageCache;
}
return nil;
}
+(id)alloc
{
@synchronized([ImageCache class])
{
NSAssert(sharedImageCache == nil, @"Attempted to allocate a second instance of a singleton.");
sharedImageCache = [super alloc];
return sharedImageCache;
}
return nil;
}
-(id)init
{
self = [super init];
if (self != nil)
{
imgCache = [[NSCache alloc] init];
}
return self;
}
- (void) AddImage:(NSString *)imageURL :(UIImage *)image
{
[imgCache setObject:image forKey:imageURL];
}
- (NSString*) GetImage:(NSString *)imageURL
{
return [imgCache objectForKey:imageURL];
}
- (BOOL) DoesExist:(NSString *)imageURL
{
if ([imgCache objectForKey:imageURL] == nil)
{
return false;
}
return true;
}
@end
要注意的是遇到顯示大量影像時,記憶體使用量會急速增長,不過不用太擔心,因為其之所以名為cache,在記憶體不夠用的時候,會先釋放它~
使用方式:
UIImage *image;
// Check the image cache to see if the image already exists. If so, then use it. If not, then download it.
if ([[ImageCache sharedImageCache] DoesExist:imgUrl] == true)
{
image = [[ImageCache sharedImageCache] GetImage:imgUrl];
}
else
{
NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: imgUrl]];
image = [[UIImage alloc] initWithData:imageData];
// Add the image to the cache
[[ImageCache sharedImageCache] AddImage:imgUrl :image];
}
參考:Cache URL images iphone UITableview、利用NSCache提升效率、25 iOS App Performance Tips & Tricks、25條提高iOS App性能的技巧和訣竅。
Comments on: "[iOS] 影像快取 (Image Cache)" (2)
[…] App工程師的自己有寫過影像快取(Image Cache) 編輯和三層級顯示影像 (Three-Level […]
讚讚
[…] 上一篇影像快取 (Image Cache)我的用法是,從網路下載影像,接著快取起來顯示,跳過儲存到手機端這個步驟,在此我用簡單的if-else說明如何實作! […]
讚讚