Just a Computer Graphics Studio & My Life

[iOS] 影像快取 (Image Cache)

時常需要從網路上抓取影像載入APP裡頭,尤其是在TableView的cell頻繁消失又出現的狀況,會不停地重複同樣(下載顯示)的動作,這樣子做不是不行,然而使用者體驗會有點差,儘管已經用多執行緒去抓圖和載圖,操作上還算相當順暢,然而使用者還是會看到影像怎麼這時候消失變出現,接著又滾回去又從消失變出現,使用者體驗實在相當糟糕⋯⋯

於是想當然爾,我們會想要把已經載入的圖給暫存起來,下次要顯示時直接抓暫存在記憶體中的影像快取 (Image Cache)即可!

在iOS中,蘋果提供NSCacheNSDictionary很相似,利用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 & Tricks25條提高iOS App性能的技巧和訣竅

Advertisements

Comments on: "[iOS] 影像快取 (Image Cache)" (2)

  1. […] App工程師的自己有寫過影像快取(Image Cache) 編輯和三層級顯示影像 (Three-Level […]

    喜歡

  2. […] 上一篇影像快取 (Image Cache)我的用法是,從網路下載影像,接著快取起來顯示,跳過儲存到手機端這個步驟,在此我用簡單的if-else說明如何實作! […]

    喜歡

發表留言

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

標籤雲

%d 位部落客按了讚: