iOS如何實現圖片緩存


在很多情況下,我們的項目中都會集成SDWebImage,但是由於版本問題,可能會造成各種的沖突。(比如集成了環信的demo,使用了比較舊的SDWebImage版本,但是自己的項目集成使用了4.0以上的版本,最要命的是使用cocoapods集成,這種沖突很難解決,版本不兼容pod install執行不過)

在這里我以集成環信Demo為例,介紹一下我自己實現的一個輕量級ImageCache框架。

環信的easeui依賴下面三個依賴,MWPhotoBrowser又依賴了SDWebImage,MBProgressHUD,DACircularProgress

  spec.dependency 'MWPhotoBrowser', '~> 2.1.1'    
  spec.dependency 'MJRefresh', '~> 3.1.0'
  spec.dependency 'Hyphenate', '~> 3.3.4'

我自己的項目也用到了SDWebImage,而且我又想用到環信IM功能。但是這個沖突很難解決,需要改很多代碼。其實我只用到了SDWebImage中很少的功能,最多就是gif,imageview可以加載網絡圖片。自己實現一個imagecache也不是一件很難的事情。

--------------------------------------------------------------------

我自己實現的圖片緩存分為3個模塊,網絡下載,任務調度,數據緩存。

首先我自己實現了一個很簡單的網絡下載功能,可以下載網絡圖片,項目地址(https://github.com/lizilong1989/LongRequest.git)

其次我自己實現了一個很簡單的任務調度功能,基於GCD實現,可以限制線程的並發,取消任務等功能,項目地址(https://github.com/lizilong1989/LongDispatch.git)

下面是我說的重點,imagecache的實現。主要原理就是LRU緩存算法,為了提供訪問的效率,我實現了兩個集合結構(數組和字典)。數組主要負責存儲key,而字典是存儲數據,LRU緩存淘汰算法主要操作的是數組,數據淘汰時同時會把字典中的數據刪除。

存儲數據:

- (void)storeCacheWithData:(NSData *)aData
                    forKey:(NSString*)aKey
                    toDisk:(BOOL)aToDisk
{
    if (![aData isKindOfClass:[NSData class]] || ![aKey isKindOfClass:[NSString class]]) {
        return;
    }
    
    if (aData.length == 0 || aKey.length == 0) {
        return;
    }
    
    pthread_mutex_lock(&_mutex);
    
    NSString *md5Key = [aKey md5String];
    
    if (CFDictionaryContainsKey(_dicRef, (__bridge const void *)aKey)) {
        [self _removeWithKey:md5Key];
        CFArrayInsertValueAtIndex(_arrayRef, 0, (__bridge const void *)aKey);
        CFDictionarySetValue(_dicRef, (__bridge const void *)aKey, CFDataCreate(0, aData.bytes, aData.length));
    } else {
        CFIndex count = CFArrayGetCount(_arrayRef);
        if (count >= kDefaultMaxCacheSize) {
            const void *key = CFArrayGetValueAtIndex(_arrayRef, count - 1);
            CFArrayRemoveValueAtIndex(_arrayRef, count - 1);
            CFDictionaryRemoveValue(_dicRef, key);
        }
        CFArrayInsertValueAtIndex(_arrayRef, 0, (__bridge const void *)aKey);
        CFDictionarySetValue(_dicRef, (__bridge const void *)aKey,CFDataCreate(0, aData.bytes, aData.length));
    }
    if (aToDisk) {
        [self _saveCacheFromDiskWithData:aData forKey:md5Key];
    }
    pthread_mutex_unlock(&_mutex);
}

獲取數據:

- (NSData*)getCacheWithKey:(NSString*)aKey
{
    NSData *obj = nil;
    if (![aKey isKindOfClass:[NSString class]] || aKey.length == 0) {
        return obj;
    }
    pthread_mutex_lock(&_mutex);
    
    NSString *md5Key = [aKey md5String];
    
    if (CFDictionaryContainsKey(_dicRef, (__bridge const void *)aKey)) {
        obj = (__bridge NSData*)CFDictionaryGetValue(_dicRef, (__bridge const void *)aKey);
    }
    if (!obj) {
        obj = [self _getCacheFromDiskWithKey:md5Key];
    }
    pthread_mutex_unlock(&_mutex);
    return obj;
}

 imagecache同時也支持播放gif,顯示webp格式圖片和簡單的圖片瀏覽等功能。

--------------------------------------------------------------------

集成Imagecache也非常簡單,支持cocoapods集成

pod 'LongImageCache'

圖片緩存使用方法

//首先引入header
#import "UIImageView+LongCache.h"

//緩存圖片
NSString *url = @"http://127.0.0.1/test.jpg";
[imageView setImageWithUrl:url placeholderImage:nil toDisk:YES];

imagecache項目地址:https://github.com/lizilong1989/LongImageCache

依賴LongImageCache的easeui地址:https://github.com/lizilong1989/easeui-ios-hyphenate-cocoapods/tree/3party_easeui

對應的環信Demo地址:https://github.com/lizilong1989/sdkdemoapp3.0_ios/tree/3rdparty_sdk3.x


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM