Number one
描述: 使用UIImage+ webImageCache下載網(wǎng)絡(luò)圖片, 自帶內(nèi)存緩存, 以及沙盒緩存;
基本方法:
[self.imageView sd_setImageWithURL: placeholderImage:];
方法描述:
-
1.根據(jù)提供的url
下載網(wǎng)絡(luò)圖片,并設(shè)置到imageView; 此時內(nèi)存中會有一份緩存,沙河中也會寫入備份; -
2. 當(dāng)再次用到該圖片時, 首先去
內(nèi)存中獲取該圖片, 內(nèi)存中沒有則去沙盒中加載, 如果都沒有就會去網(wǎng)絡(luò)下載;
注意:該方法底層會首先取消imageView之前的任務(wù), 防止數(shù)據(jù)錯亂.
// 取消iamgeView之前的下載任務(wù)
[self.imageView sd_cancelCurrentImageLoad];
解析: 因為該方法有一個完成回調(diào)block, 當(dāng)有網(wǎng)絡(luò)延時時,
下載圖片太慢, imageview循環(huán)利用顯示其他圖片, 但此時前面的下載任務(wù)下載好了,
就會拿到imageView直接設(shè)置圖片, 會導(dǎo)致數(shù)據(jù)錯亂;
故在之前調(diào)用該方法, 可以防止數(shù)據(jù)引用;
方法總結(jié)
- 1.0 取消
當(dāng)前imageView之前關(guān)聯(lián)的請求 - 2.0 設(shè)置
占位圖片到當(dāng)前的imageview - 3.0 如果緩存(
內(nèi)存, 沙盒)中有圖片則直接設(shè)置, 不使用占位圖片 - 4.0 如果沒有,則
發(fā)送請求下載圖片
Number two
怎么實現(xiàn)緩存,以及獲取對應(yīng)的圖片
- 無論是
內(nèi)存緩存, 還是沙盒緩存都是以字典的形式保存圖片, 因為SDImageCache使用了NSCache類 - key :
圖片的url; value:下載的圖片
Number three
代碼實現(xiàn):
核心概念:
-
根據(jù)
不同網(wǎng)絡(luò),下載不同圖片(省流量) -
內(nèi)存緩存中,
只保存當(dāng)前顯示的圖片 -
其他只保存到沙盒,
用到時才會緩存到內(nèi)存 (提高內(nèi)存性能)
1.0 監(jiān)聽用戶網(wǎng)絡(luò)狀態(tài)
AFNetworkReachabilityManager
// 程序啟動的時候調(diào)用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 監(jiān)控網(wǎng)絡(luò)狀態(tài)
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
return YES;
}
2.0 根據(jù)不同網(wǎng)絡(luò)狀態(tài), 下載不同圖片
// 占位圖片
UIImage *placeholder = nil;
// 1.0 從緩存中獲得原圖
// 該方法會首先去內(nèi)存找, 再去沙盒
UIImage *originalImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:originalImageUrl];
if (originalImage) { // 如果緩存有原圖,那么就直接顯示原圖(不管現(xiàn)在是什么網(wǎng)絡(luò)狀態(tài))
[self.imageView sd_setImageWithURL:[NSURL URLWithString:originalImageUrl] placeholderImage:placeholder];
} else {
// 2.0 緩存沒有原圖, 根據(jù)網(wǎng)絡(luò)下載
AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]
// 在使用Wifi, 下載原圖
if (mgr.isReachableViaWiFi) {
[self.imageView sd_setImageWithURL:[NSURL URLWithString:originalImageUrl] placeholderImage:placeholder];
// 在使用手機自帶網(wǎng)絡(luò)
} else if (mgr.isReachableViaWWAN) {
// 下載小圖
[self.imageView sd_setImageWithURL:[NSURL URLWithString:thumbnailmageUrl] placeholderImage:placeholder];
} else {
// 3.0 沒有網(wǎng)絡(luò)
UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:thumbnailImageUrl];
if (thumbnailImage) { // 緩存中有小圖
[self.imageView sd_setImageWithURL:[NSURL URLWithString:thunmnailImage] placeholderImage:placeholder];
} else {// 沒有小圖
[self.imageView sd_setImageWithURL:nil placeholderImage:placeholder];
}
}
}
3.0 處理緩存圖片, 內(nèi)存飆升問題
首先:
-
SDImageCache怎么處理內(nèi)存問題?
// 清空沙盒過期圖片 (七天為限)
- (void)cleanDisk;
// 清空沙盒內(nèi)所有圖片
- (void)clearDisk;
// 清空內(nèi)存緩存所有圖片
- (void)clearMemory;
- 什么時候處理
// 獲取自動清理緩存對象
_memCache = [[AutoPurgeCache alloc] init];
// 當(dāng)接收到內(nèi)存警告, 才會處理緩存
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
只有內(nèi)存警告時才會處理?
為了用戶體驗故需我們手動釋放:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 滾動時, 清除緩存
[[SDImageCache sharedImageCache] clearMemory];
}
解析: 為什么緩存中所有圖片都清空了, imageView還能顯示圖片?
-
圖片字典的形式保存在緩存中, NSCache有保存所有的key, 每個key指向一個圖片對象
-
[self.memCache removeAllObjects]會把指向圖片的key清掉, 則沒有強引用的圖片會被釋放; -
但是當(dāng)把圖片設(shè)置到
imageview上時,image指針會強引用圖片, 故還能顯示圖片
圖示: ###
另外一個問題:
由于使用模擬器測試,發(fā)現(xiàn)在滾動過程中, 釋放內(nèi)存造成有時卡頓效果, 故在具體使用時, 還得各自思量;
tips: 建議把該方法抽取為(UIImageView)一個分類, 以便代碼復(fù)用;
有問題, 請留言...