在很多情況下,我們的項目中都會集成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