1.概述

SDWebImage是iOS开发中,被广泛使用的一个第三方开源库,提供了图片从加载、解析、处理、缓存、清理等一些列功能,让我们能够专心于业务的处理。本篇会从SDWebImage的源码,来一步步分析,让我们更加的熟悉和了解它,以达到更好的应用的目的。

SDWebImage最常用的方法就是下面这个,我们在实际开发中,大部分时间只是用到了这个方法:

[self.imageView sd_setImageWithURL:[NSURL URLWithString:@"url"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

SDWebImage的设计是极其的优雅和简洁, 主要的功能就是这么一行代码, 而其中复杂的实现细节全部隐藏在这行代码之后。

下图是SDWebImage官方的类图:

通过对上面图片的分析,我们可以将SDWebImage的类分为三大类型:视图分类;工具类;核心类。

1.1视图分类

这部分包含的类主要有如下几个:

  • UIButton(WebCache)UIButton类加载图片的方法。比如正常情况下、点击情况下的image属性和背景图片等。
  • MKAnnotationView(WebCache):MKAnnotationView类添加各种加载图片的方法。
  • UIImageView(WebCache)UIImageView类添加加载图片的方法。
  • UIImageView(HighlightedWebCache)UIImageView类添加高亮状态下加载图片的方法。
  • FLAnimatedImageView(WebCache):FLAnimatedImageView类添加加载动态的方法,这个分类需要引入FLAnimatedImage框架。SDWebImage推荐使用这个框架来处理动态图片(GIF)的加载。
  • UIView(WebCache):上面几个分类,都会调用本分类的sd_internalSetImageWithURL方法来做图片加载请求,具体是通过SDWebImageManager调用来实现的。它还实现了Operation取消、ActivityIndicator的添加与取消。同时通过UIView+WebCacheOperation分类来管理请求的取消和记录工作。

1.2工具类

  • NSData+ImageContentType: 根据图片数据获取图片的类型,比如GIF、PNG等。
  • SDWebImageCompat: 该配置文件主要是兼容Apple的其他设备,包含很多宏定义以及一个根据key修改图片尺寸的方法。
  • SDImageCacheConfig: 用来管理缓存配置信息。比如是否解码、是否允许iCloud、是否允许内存缓存、缓存时间等。默认的缓存时间是一周。
  • UIImage+MultiFormat: 获取UIImage对象对应的data、或者根据data生成指定格式的UIImage,其实就是UIImage和NSData之间的转换处理。
  • UIImage+GIF: 对于一张图片是否GIF做判断。可以根据NSData返回一张GIF的UIImage对象,并且只返回GIF的第一张图片生成的GIF。如果要显示多张GIF,使用FLAnimatedImageView
  • SDWebImageDecoder: 根据图片的情况,做图片的解码处理,并且根据图片的情况决定如何处理解码。

1.3核心类

  • SDImageCache: 负责SDWebImage的整个缓存工作,是一个单例对象。缓存路径处理、缓存名字处理、管理内存缓存和磁盘缓存的创建和删除、根据指定key获取图片、存入图片的类型处理、根据缓存的创建和修改日期删除缓存。
  • SDWebImageManager: 这个类是一个单例。拥有一个SDWebImageCacheSDWebImageDownloader属性分别用于图片的缓存和加载处理。为UIView及其子类提供了加载图片的统一接口。管理正在加载操作的集合,还有就是各种加载选项的处理。
  • SDWebImageDownloader: 实现了图片加载的具体处理,如果图片在缓存则从缓存区加载。如果缓存不存在,则直接创建一个。同时管理NSURLRequest对象请求头的封装、缓存、cookie的设置。加载选项的处理等功能。管理Operation之间的依赖关系。
  • SDWebImageDownloaderOperation: 一个自定义的并行Operation子类。这个类主要实现了图片下载的具体操作、以及图片下载完成以后的图片解码、Operation生命周期管理等。
  • FLAnimatedImageView: 动态图片的数据通过ALAnimatedImage对象来封装。FLAnimatedImageViewUIImageView的子类。通过它完全可以实现动态图片的加载显示和管理。并且对UIImageView做了流程优化。

2.实现流程

SDWebImage为我们实现了图片加载、数据处理、图片缓存等一些列工作。下面我们通过官方的图来看一下相关操作的流程:

通过上图,我们知道SDWebImage加载的过程是首先从缓存中加载数据,缓存加载是优先从内存缓存中加载,然后才是磁盘加载。如果没有缓存,才从网络上加载。网络成功加载图片以后,存入本地缓存。

3.SDWebImage源码解读

  1. SDWebImage之工具类
  2. SDWebImage之SDWebImageCompat
  3. SDWebImage之SDWebImageManager
  4. SDWebImage之SDImageCache
  5. SDWebImage之SDWebImageDownloader
  6. SDWebImage之SDWebImageDownloaderOperation
  7. SDWebImage之UIView+WebCache

4.总结

通过对SDWebImage开源库的学习,大致有如下几点让我收获较多:

  • 解耦的思想:在我们实际的项目开发中,往往容易忽略解耦的重要性,最终导致代码量越来越多,也越来越乱,增大了代码的维护成本,也间接的降低了代码的质量。在SDWebImage中,核心类是SDWebImageManager,在这个类中,它又把两项重要的职责:缓存管理、下载管理,拆分给SDImageCacheSDWebImageDownloader,这样,作为核心类的SDWebImageManager,功能和思想以及代码的维护相对来说要容易很多。
  • 清晰的功能流程:从图片的下载到图片显示到视图上,SDWebImage的流程非常清晰。首先从缓存中加载数据,缓存加载又是优先从内存缓存中加载,然后才是磁盘加载。最后如果缓存没有,才从网络上加载。同时网络成功加载图片以后,存入本地缓存。
  • 优秀的性能细节处理:通过使用GCD和NSOperation的结合使用,来提升用户性能上的体验提升;
  • 简洁的API:采用Category,让我们能像使用视图的原生API一样,简易的进行操作。

SDWebImage源码分析的更多相关文章

  1. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  2. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  3. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

  4. 【原】SDWebImage源码阅读(五)

    [原]SDWebImage源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 前面的代码并没有特意去讲SDWebImage的缓存机制,主要是想单独开一章节专门讲 ...

  5. 【原】SDWebImage源码阅读(三)

    [原]SDWebImage源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1.SDWebImageDownloader中的downloadImageWithURL 我们 ...

  6. 【原】SDWebImage源码阅读(二)

    [原]SDWebImage源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 解决上一篇遗留的坑 上一篇中对sd_setImageWithURL函数简单分析了一下,还 ...

  7. SDWebImage源码刨根问底

    前言: SDWebImage是iOS中一款处理图片的框架, 使用它提供的方法, 一句话就能让UIImageView,自动去加载并显示网络图片,将图片缓存到内存或磁盘缓存,正好有阅读开源项目的计划,于是 ...

  8. SDWebImage源码阅读-第三篇

    这一篇讲讲不常用的一些方法. 1 sd_setImageWithPreviousCachedImageWithURL: placeholderImage: options: progress: com ...

  9. iOS常用框架源码分析

    SDWebImage NSCache 类似可变字典,线程安全,使用可变字典自定义实现缓存时需要考虑加锁和释放锁 在内存不足时NSCache会自动释放存储的对象,不需要手动干预 NSCache的key不 ...

随机推荐

  1. Django模板语言相关内容 Djan

    Django模板语言相关内容   Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} ...

  2. 图释SQL的Join

    对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codin ...

  3. 高并发高负载系统架构-php篇

    首先呢,我罗列一下文章的目录,让大家有个整体轮廓的了解! 1.为什么要进行高并发和高负载的研究 2.高并发和高负载的约束条件 3.解决之道——硬件篇 4.解决之道——部署篇 5.解决之道——环境篇 6 ...

  4. metrics+spring+influxdb整合

    1.在maven项目的pom.xml引入metrics-spring和metrics-influxdb两个jar包 <dependency> <groupId>com.ryan ...

  5. Unity网格合并_材质合并

    [转]Unity网格合并_材质合并 原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网 ...

  6. POJ2456Aggressive cows-(二分判定)

    Description Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stal ...

  7. UGUI中Text的换行

    通过代码中的\n可以直接执行换行效果,但是我们在平常的工作中一般都是读表,既在Inspector面板中的Text组件中输入同样的内容就达不到换行效果: 其实unity把\n转变成了\\n,我们只需要变 ...

  8. SpringAOP日志配置

    SpringAOP日志配置 配置文件配置 l  配置spring-mvc.xml <aop:config proxy-target-class="true" /> &l ...

  9. typescript里面调用javasript

    index.html 里面加入函数: function tellYou() { egret.log("tell you."); javascript:android.funA(); ...

  10. 面试简单整理之JVM

    194.说一下 jvm 的主要组成部分?及其作用? JVM内存分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据. 堆内存用于存储使用new关键字所创建的对象: 栈内存用于存储程序运行时在 ...