時常需要從網路上抓取影像載入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說明如何實作! […]
讚讚