IOS 網絡-深入淺出(一 )


首要我們以最為常用的UIImageView為例介紹實現原理:

1)UIImageView+WebCache:  setImageWithURL:placeholderImage:options: 先顯示 placeholderImage ,同時由SDWebImageManager 根據 URL 來在本地查找圖片。

2)SDWebImageManager: downloadWithURL:delegate:options:userInfo: SDWebImageManager是將UIImageView+WebCache同SDImageCache鏈接起來的類, SDImageCache: queryDiskCacheForKey:delegate:userInfo:用來從緩存根據CacheKey查找圖片是否已經在緩存中

3)如果內存中已經有圖片緩存, SDWebImageManager會回調SDImageCacheDelegate : imageCache:didFindImage:forKey:userInfo:

4)而 UIImageView+WebCache 則回調SDWebImageManagerDelegate:  webImageManager:didFinishWithImage:來顯示圖片。

5)如果內存中沒有圖片緩存,那么生成 NSInvocationOperation 添加到隊列,從硬盤查找圖片是否已被下載緩存。

6)根據 URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進行的操作,所以回主線程進行結果回調 notifyDelegate:。

7)如果上一操作從硬盤讀取到了圖片,將圖片添加到內存緩存中(如果空閑內存過小,會先清空內存緩存)。SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo:。進而回調展示圖片。

8)如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片,需要下載圖片,回調 imageCache:didNotFindImageForKey:userInfo:。

9)共享或重新生成一個下載器 SDWebImageDownloader 開始下載圖片。

10)圖片下載由 NSURLConnection 來做,實現相關 delegate 來判斷圖片下載中、下載完成和下載失敗。

11)connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度加載效果。

12)connectionDidFinishLoading: 數據下載完成后交給 SDWebImageDecoder 做圖片解碼處理。

13)圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。如果有需要對下載的圖片進行二次處理,最好也在這里完成,效率會好很多。

14)在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調給 SDWebImageDownloader。

15)imageDownloader:didFinishWithImage: 回調給 SDWebImageManager 告知圖片下載完成。

16)通知所有的 downloadDelegates 下載完成,回調給需要的地方展示圖片。

17)將圖片保存到 SDImageCache 中,內存緩存和硬盤緩存同時保存。

18)寫文件到硬盤在單獨 NSInvocationOperation 中完成,避免拖慢主線程。

19) 如果是在iOS上運行,SDImageCache 在初始化的時候會注冊notification 到 UIApplicationDidReceiveMemoryWarningNotification 以及  UIApplicationWillTerminateNotification,在內存警告的時候清理內存圖片緩存,應用結束的時候清理過期圖片。

20)SDWebImagePrefetcher 可以預先下載圖片,方便后續使用。

*以上為轉載*

*以下為原創*

 

SDWebImage主要是用於網絡圖片的獲取。

當然也可用於其他操作。

例如對button的操作,不過都是大同小異。

因此在這里不過多嘮叨。

重點是理解SDWebImage是如何實現,並且該如何使用。

//
// ViewController.m
// CX-深入淺出 SDWebImage
//
// Created by ma c on 16/3/24.
// Copyright © 2016年 xubaoaichiyu. All rights reserved.
//

#import "ViewController.h"
#import "UIImageView+WebCache.h"
//由於網絡問題這里使用的是本地服務器
static NSString * urlString = @"http://localhost/nvshen.jpeg";
@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIImageView
*imageVIew;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
}

- (IBAction)downLoad:(id)sender {

/*
options所有選項:

//失敗后重試 (經常使用)
SDWebImageRetryFailed = 1 << 0,

//UI交互期間開始下載,導致延遲下載比如UIScrollView減速。(經常使用)
SDWebImageLowPriority = 1 << 1,

//只進行內存緩存
SDWebImageCacheMemoryOnly = 1 << 2,

//這個標志可以漸進式下載,顯示的圖像是逐步在下載
SDWebImageProgressiveDownload = 1 << 3,

//刷新緩存
SDWebImageRefreshCached = 1 << 4,

//后台下載
SDWebImageContinueInBackground = 1 << 5,

//優先下載
SDWebImageHighPriority = 1 << 8,

//延遲占位符
SDWebImageDelayPlaceholder = 1 << 9,

//改變動畫形象
SDWebImageTransformAnimatedImage = 1 << 10,

*/
/*
只是獲取圖片
1)self.imageVIew sd_setImageWithURL:[NSURL URLWithString:urlString]
獲取圖片 完成后可操作
2)[self.imageVIew sd_setImageWithURL:[NSURL URLWithString:urlString] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

}];
獲取動畫(圖片組)
3)self.imageVIew sd_setAnimationImagesWithURLs:<#(NSArray *)#>
從之前緩存里獲取
4)self.imageVIew sd_setImageWithPreviousCachedImageWithURL:<#(NSURL *)#> placeholderImage:<#(UIImage *)#> options:<#(SDWebImageOptions)#> progress:<#^(NSInteger receivedSize, NSInteger expectedSize)progressBlock#> completed:<#^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)completedBlock#>

*/
//較完整的操作
/*
URl:這里是網絡地址
placeholderImage:占為圖片,在下載完成前顯示
options:操作選項
completed:完成后->
*/
[self.imageVIew sd_setImageWithPreviousCachedImageWithURL:[NSURL URLWithString:urlString] placeholderImage:nil options:SDWebImageRetryFailed progress:
^(NSInteger receivedSize, NSInteger expectedSize) {
//這里是下載進度
//receivedSize 已經下載的大小
//expectedSize 總大小
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//下載完成后
//可以是成功,也可以是失敗。
}];

}

@end

有時候我們需要測試圖片是否真正存入到沙盒內,因此我們需要獲取到沙盒的地址。

方法如下

    NSString * path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSLog(
@"%@",path);

獲取地址后我們可以在終端打開

⬇️GIF⬇️


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com