2018-06-06 SDWebImage深度学习

2018-06-06  本文已影响52人  破夕_____________

SDWebImage

1.它是iOS图片加载框架

它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件。在项目中使用SDWebImage来管理图片加载相关操作可以极大地提高开发效率,让我们更加专注于业务逻辑实现。

实现原理:其实SDWebImage之所以能够实现缓存的原理关键就是在哪个key值。

**-** (void)**sd_setImageWithPreviousCachedImageWithURL**:(NSURL *)**url****andPlaceholderImage**:(UIImage *)**placeholder****options**:(SDWebImageOptions)options**progress**:(SDWebImageDownloaderProgressBlock)progressBlock**completed**:(SDWebImageCompletionBlock)completedBlock;

比如使用它的时候,其实就是把url当做了一个图片的key值,然后存储对应的图片,如果下次请求的url和这次请求的url一样,那么就直接根据url(这个key)来取图片,如果url作为key的图片缓存不存在,就去请求远程服务器,然后请求过来之后再次将url和图片对应,然后存储。

2.SDWebImage 概论

1.提供了一个UIImageView的category用来加载网络图片并且对网络图片的缓存进行管理

2.采用异步方式来下载网络图片

3.采用异步方式,使用memory+disk来缓存网络图片,自动管理缓存。

4.支持GIF动画

5.支持WebP格式

6.同一个URL的网络图片不会被重复下载

7.失效的URL不会被无限重试

8.耗时操作都在子线程,确保不会阻塞主线程

9.使用GCD和ARC

注意:SDWebImage 使用NSOperationQueue 线程队列来处理多线程。耗时操作都是在子线程里处理。

_downloadQueue = [NSOperationQueuenew];

_downloadQueue.maxConcurrentOperationCount =6;

最大maxConcurrentOperationCount  最大并发队列为6.

/********************************************************************/

一、****options****所有选项:

 | 

  //失败后重试

     SDWebImageRetryFailed = 1 << 0,

     //UI交互期间开始下载,导致延迟下载比如UIScrollView减速。

     SDWebImageLowPriority = 1 << 1,

     //只进行内存缓存

     SDWebImageCacheMemoryOnly = 1 << 2,

     //这个标志可以渐进式下载,显示的图像是逐步在下载

     SDWebImageProgressiveDownload = 1 << 3,

     //刷新缓存

     SDWebImageRefreshCached = 1 << 4,

     //后台下载

     SDWebImageContinueInBackground = 1 << 5,

     //NSMutableURLRequest.HTTPShouldHandleCookies = YES;

     SDWebImageHandleCookies = 1 << 6,

     //允许使用无效的SSL证书

     //SDWebImageAllowInvalidSSLCertificates = 1 << 7,

     //优先下载

     SDWebImageHighPriority = 1 << 8,

     //延迟占位符

     SDWebImageDelayPlaceholder = 1 << 9,

     //改变动画形象

     SDWebImageTransformAnimatedImage = 1 << 10,

 |

/********************************************************************/

UIImageView+WebCache.h

1. UIImageView的category,来添加新的方法。

/* Set the imageView `image` with an `url`,The download is asynchronous and cached.*/

2.- (void)sd_setImageWithURL:(NSURL *)url;

/*@param placeholder The image to be set initially, until the image request finishes.*/

3.- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;

/*@param options 主要看SDWebImageOptions的枚举*/

4.- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;

/*completedBlock A block called when operation has been completed*/

5.- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;

/*同上,只是多了placeholderImage*/

6.- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;

/*同上,只是多了SDWebImageOptions枚举*/

7.- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;

/*同上,只是多了progress*/

8.- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;

/*PreviousCached*/

9.- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;

/*以用一组图片生成动画:*/

10.- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs;

11./*Cancel the current download*/

- (void)sd_cancelCurrentImageLoad;

- (void)sd_cancelCurrentAnimationImagesLoad;

/*Show activity UIActivityIndicatorView  菊花显示*/

12.- (void)setShowActivityIndicatorView:(BOOL)show;

/*@param style The style of the UIActivityIndicatorView 菊花样式*/

13.- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;

pod 'UIActivityIndicator-for-SDWebImage' 一个帮助使用SDWebImage带有UIActivityIndicator的pod

读.m (使用了objc/runtime.h)

主要有三点:

1\. 先移除已有的operationsd_cancelImageLoadOperationWithKey

2.帮助imageView添加UIActivityIndicatorView操作。

3.使用SDWebImageManager类下载url,并返回相应的block,同时把这个下载operation添加到operationDictionary队列中。

/********************************************************************/

UIButton+WebCache.h

//  UIButton加载图片

/*与UIImageView不同的是多了UIControlState*/

1.- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;

/*设置BackgroundImage*/

2.- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;

3.其他的一些方法都是这两个的子集,不在介绍。

读.m   跟UIImageView+WebCache的.m 基本一样。

/********************************************************************/

UIImage+GIF.h 这个类别就是让UIImageView能显示gif 的类别。

/*通过这个方法加载gif*/

1.+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;

主要学习到:加载gif 的原理 实质是一定时间内加载多个image。

1.将gif 文件读取后,转化为data 类型

2.将data 转化为CGImageSourceRef,可以获取组成gif的image的个数。

3.然后重新转化为data-> image 

    4.利用UIImage的动画属性设置即可:[UIImageanimatedImageWithImages:imagesduration:duration];

/********************************************************************/

UIImage+MultiFormat.h 这个类别就是能加载:多种类型的图片格式png,gif,tiffjpeg.

1.+ (UIImage *)sd_imageWithData:(NSData *)data;

NSData+ImageContentType.h   这个类别是判断图片 data  的类型png,gif,tiffjpeg等。

1.+ (NSString *)sd_contentTypeForImageData:(NSData *)data;

UIView+WebCacheOperation.h这个类别是作为父类的为子类(UIImageView 、UIButton)提供服务的

/*存储operation 到字典、取消operation、移除operation、*/

- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key;

- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key;

- (void)sd_removeImageLoadOperationWithKey:(NSString *)key;

UIImageView+HighlightedWebCache.h  这个类别是设置UIImageView高亮状态下的image 。

 方法和UIImageView+WebCache 一致。

/********************************************************************/

类别看完了,下面是真正SDWebImage 帮我们实现url下载,缓存的类。

核心类

SDWebImageManager.h  是个单例类

/*Returns global SDWebImageManager instance. */

@property (strong,nonatomic,readonly)SDImageCache *imageCache;

@property (strong,nonatomic,readonly)SDWebImageDownloader *imageDownloader;

1.+ (SDWebImageManager *)sharedManager;

/*初始化带有上面两个属性的实例化。*/

2.- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader;

/*

SDWebImage 第三方库的核心方法

如果在缓存中不存在,则在给定URL处下载图像,否则返回缓存版本。

@param url            The URL to the image

@param options       SDWebImageOptions

@param progressBlock  SDWebImageDownloaderProgressBlock

@param completedBlock SDWebImageCompletionWithFinishedBlock

 */

3.- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock

 completed:(SDWebImageCompletionWithFinishedBlock)completedBlock;

实现过程

1.加锁访问:判断url是否在failedURLs数组中。如果存在则不在持续请求。直接返回失败block。

2.加锁访问:将operation操作对象添加到已存在的runningOperations队列数组。

3. 根据url去缓存中去取key。NSString *key = [self cacheKeyForURL:url];

4.第一步:先去内存(Memory)高速缓存中去取,有则返回image 和CacheType 类型。

UIImage *image = [selfimageFromMemoryCacheForKey:key];

doneBlock(image, SDImageCacheTypeMemory);

第二步:没有继续去磁盘(Disk)高速缓存中去,有则先写入Memory,如空间不足,通过添加通知UIApplicationDidReceiveMemoryWarningNotification得知内存警告,清空缓存。然后返回Disk中的image 和CacheType 类型。

UIImage *diskImage = [selfdiskImageForKey:key];

if (diskImage &&self.shouldCacheImagesInMemory) {

NSUInteger cost =SDCacheCostForImage(diskImage);

[self.memCachesetObject:diskImageforKey:keycost:cost];

    }

doneBlock(diskImage, SDImageCacheTypeDisk);
第三步:如果前者仍没有找到,说明所有缓存都不存在该图片,需要下载图片。SDWebImageDownloader类去处理下载使用NSMutableURLRequest使用NSURLSession发起请求。 让SDWebImageDownloaderOperation这个类专门封装NSURLSession请求,并实现NSURLSessionDataDelegate代理,处理接受数据回调。整个url下载完成。

/********************************************************************/

主要类

SDWebImageDownloader.h

发起http请求下载类,NSURLSession发请求,和实现代理。

SDWebImageDownloaderOperation.h

将SDWebImageDownloader数据回调到本类中。

SDImageCache.h

缓存处理对象,存储store,取query,删除remove,清除clear等的操作。

我们可以使用它做本地缓存:

很多时候我们可能拍照得到的一张图片要多个地方使用,那么我们就希望可以把这张图片放到缓存里面,然后每次用这张图片的时候就去通过特定的方式取即可。SDWebImage就有这样的一个类:SDImageCache。该类完美地帮助了我们解决了这个问题。

存图片:

SDImageCache *imageCache = [SDImageCache sharedImageCache];

[imageCache storeImage:imageforKey:@"myphoto"toDisk:YES];

取图片:

SDImageCache *imageCache = [SDImageCache sharedImageCache];

**UIImage** *image = [imageCache imageFromDiskCacheForKey:@"myphoto"];

其他类:

SDWebImageDecoder.h

强制解压缩类 ForceDecode

SDWebImageCompat.h

转换2x,3ximage

SDWebImagePrefetcher.h

预取供将来使用缓存中的某些 Url。在低优先级中下载图像。

// Url 在同一时间预取的最大数目。默认值为 3。


@property (nonatomic, assign) NSUInteger maxConcurrentDownloads

// Prefetcher 的 SDWebImageOptions。默认值为 SDWebImageLowPriority。

@property (nonatomic, assign) SDWebImageOptions options

+ (SDWebImagePrefetcher *)sharedImagePrefetcher

/*删除和取消排队的列表*/

- (void)cancelPrefetching

/*分配让SDWebImagePrefetcher排队预取的 Url 的列表,目前一个图像,一次下载和跳过失败的下载的图像和进行到列表中的下一个图像*/

@parame url  要预取的 Url 的列表

- (void)prefetchURLs:(NSArray *)*urls*

/*分配让SDWebImagePrefetcher排队预取的 Url 的列表,目前一个图像,一次下载和跳过失败的下载的图像和进行到列表中的下一个图像 */

@parame url要预取的 Url 的列表

@parame completionBlock 为预取完毕的回调

- (void)prefetchURLs:(NSArray *)*urls* completed:(void ( ^ ) ( NSUInteger finishedCount , NSUInteger skippedCount ))*completionBlock* 

/********************************************************************/

参考:[http://www.cocoachina.com/ios/20141212/10622.html](http://www.cocoachina.com/ios/20141212/10622.html)

[http://www.tuicool.com/articles/rA3IryE](http://www.tuicool.com/articles/rA3IryE)

[http://blog.csdn.net/ios_apple/article/details/24310719](http://blog.csdn.net/ios_apple/article/details/24310719)
https://blog.csdn.net/shifang07/article/details/71511917
上一篇下一篇

猜你喜欢

热点阅读