美文网首页
2018-06-06 SDWebImage深度学习

2018-06-06 SDWebImage深度学习

作者: 破夕_____________ | 来源:发表于2018-06-06 10:46 被阅读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
    

    相关文章

      网友评论

          本文标题:2018-06-06 SDWebImage深度学习

          本文链接:https://www.haomeiwen.com/subject/qlxbsftx.html