1. 在tableView
中使用UIImageView + WebCache
分類
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided sd_setImageWithURL: method to load the web image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
}
2. 使用Block
,可以通過block
獲取圖片下載的進度信息,及成功後要進行的操作
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
... completion code here ...
}];
3. 使用SDWebImageManager
描述,這是在
UIImageView
之後的一個分類,其在圖片緩存中使用了異步下載機制,你可以直接使用其進行處理一些信息。
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:imageURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
// do something with image
}
}];
4. 單獨使用異步下載機制
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
[downloader downloadImageWithURL:imageURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
if (image && finished) {
// do something with image
}
}];
5. 使用圖片成功後刷新:
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
options:SDWebImageRefreshCached];
sdWebImage
支持異步的圖片下載+緩存
入口
setImageWithURL:placeholderImage:options:
會先把placeholderImage
顯示,然後SDWebImageManager
根據URL
開始處理圖片。進入
SDWebImageManager-downloadWithURL:delegate:options:userInfo:
,交給
SDImageCache
從緩存查找圖片是否已經下載queryDiskCacheForKey:delegate:userInfo:
.先從內存圖片緩存查找是否有圖片,如果內存中已經有圖片緩存,
SDImageCacheDelegate
回調imageCache:didFindImage:forKey:userInfo:
到SDWebImageManager
。SDWebImageManagerDelegate
回調webImageManager:didFinishWithImage:
到UIImageView+WebCache
等前端展示圖片。如果內存緩存中沒有,生成
NSInvocationOperation
添加到隊列開始從硬盤查找圖片是否已經緩存。根據
URLKey
在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在NSOperation
進行的操作,所以回主線程進行結果回調notifyDelegate
:。如果上一操作從硬盤讀取到了圖片,將圖片添加到內存緩存中(如果空閒內存過小,會先清空內存緩存)。
SDImageCacheDelegate
回調imageCache:didFindImage:forKey:userInfo:
。進而回調展示圖片。如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片,需要下載圖片,回調
imageCache:didNotFindImageForKey:userInfo:
。共享或重新生成一個下載器
SDWebImageDownloader
開始下載圖片。圖片下載由
NSURLConnection
來做,實現相關delegate
來判斷圖片下載中、下載完成和下載失敗。connection:didReceiveData:
中利用ImageIO
做了按圖片下載進度加載效果。connectionDidFinishLoading:
數據下載完成後交給SDWebImageDecoder
做圖片解碼處理。圖片解碼處理在一個
NSOperationQueue
完成,不會拖慢主線程UI
。如果有需要對下載的圖片進行二次處理,最好也在這裏完成,效率會好很多。在主線程
notifyDelegateOnMainThreadWithInfo:
宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo:
回調給
SDWebImageDownloader
。imageDownloader:didFinishWithImage:
回調給SDWebImageManager
告知圖片下載完成。通知所有的
downloadDelegates
下載完成,回調給需要的地方展示圖片。將圖片保存到
SDImageCache
中,內存緩存和硬盤緩存同時保存。寫文件到硬盤也在以單獨NSInvocationOperation
完成,避免拖慢主線程。SDImageCache
在初始化的時候會註冊一些消息通知,在內存警告或退到後臺的時候清理內存圖片緩存,應用結束的時候清理過期圖片。SDWI
也提供了UIButton+WebCache
和MKAnnotationView+WebCache
,方便使用。SDWebImagePrefetcher
可以預先下載圖片,方便後續使用。如果使用
UIButton+WebCache
,加載出圖片會根據系統的scale
進行相應的圖片尺寸縮放處理,UIImageView
則不會進行這樣處理。
參考資料: