SDWebImage框架重要的细节

http://www.jianshu.com/p/9bbb258c063f


SDWebImage框架重要的细节

SDWebImage框架重要的细节_第1张图片 
作者  Enrica  关注
2017.02.13 11:05  字数 1897  阅读 104 评论 0

  我们在前面的笔记《SDWebImage的基本使用》中学习了该框架的一些基本知识,接下来,再看一下它内部的一些细节。

  1、最大并发数

  在学习NSOperation的时候,我们知道,线程的最大并发数默认值是-1,也就是不设限。那么,在SDWebImage中,线程的最大并发数是多少呢?

  在《多线程技术的综合应用》这篇笔记中,我们下载网络图片的代码,其实主要是分为两大部分:一部分是用来处理缓存的,另一部分是用来开子线程的。再来看SDWebImage框架,它其实也可以分为两部分,即一部分用来处理缓存,另一部分用来处理下载。

  在SDWebImage这个框架中,最重要的一个类是SDWebImageManager,它主要分管两大部分内容:SDImageCache(处理缓存文件)和SDWebImageDownloader(处理图片的下载)。而在处理下载图片的类中,真正执行任务的是SDWebImageDownloaderOperation。要查看SDWebImage中线程的最大并发数,就应该去处理下载的类中寻找。

  在SDWebImageDownloader这个类中,有一个属性maxConcurrentDownloads,就是用来表示最大下载量(也就是最大并发数)的。我们来看一下它的初始化代码:


maxConcurrentDownloads.png

  从代码上看,它是直接返回_downloadQueue.maxConcurrentOperationCount。那么,这个东西所代表的实际数值又是多少呢?继续在SDWebImageDownloader这个类中查看,你会看到一个- init方法,在这里,我们看到_downloadQueue.maxConcurrentOperationCount的数值是6。也就是说,在SDWebImage中,下载任务的最大并发数是6

SDWebImage框架重要的细节_第2张图片
默认最大的并发数.png

  2、队列中任务的执行顺序

  在SDWebImageDownloader这个类中,有一个属性executionOrder,它表示任务的执行顺序,其类型是一个枚举。可以进到这个枚举的实现代码中看一下:

SDWebImage框架重要的细节_第3张图片
SDWebImageDownloaderExecutionOrder.png

  这个枚举总共只有两个成员,其中,SDWebImageDownloaderFIFOExecutionOrder表示队列中的任务按照"先进先出"的顺序执行;而SDWebImageDownloaderLIFOExecutionOrder表示队列中的任务按照"后进先出"的顺序执行。再回到- init方法中,我们看到,executionOrder默认是按照"先进先出"的顺序执行任务的

SDWebImage框架重要的细节_第4张图片
队列中任务默认的执行顺序.png

  3、缓存文件的命名

  在《多线程技术的综合应用》这篇笔记中,当时我们处理沙盒缓存的时候,缓存文件的命名用的是图片URL地址最后一个节点。那么,在SDWebImage框架中,它又是怎么命名沙盒缓存文件的名称呢?可以进入项目沙盒缓存目录去看一下(具体的进入方式,参见《如何快速定位应用的沙盒存放路径》):

SDWebImage框架重要的细节_第5张图片
图片在沙盒缓存中的名称.png

  从图片的URL地址,以及它在沙盒中缓存文件的名称上看,显然不是简单的用URL地址最后一个节点的名称来命名的。实际上,缓存文件的命名还是和图片的URL地址有关系,只不过,它多做了一层处理。

  在SDWebImage中,沙盒缓存文件的命名是用图片的URL地址经过MD5加密之后得到的字符串儿来命名的。可以在终端用 echo -n "图片的URL地址" | md5命令来验证:

SDWebImage框架重要的细节_第6张图片
对图片的URL地址做MD5加密处理.png

  从上面的图中,我们看到,经过MD5加密过后的URL地址所得到的字符串儿,正好和上面沙盒中缓存文件的名称一致。

  4、对内存警告的处理

  在发生内存警告的时候,SDWebImage是怎么处理的呢?在上一篇笔记《SDWebImage的基本使用》中,我们通过在AppDelegate中实现- applicationDidReceiveMemoryWarning:方法来处理这个问题。其实,在SDWebImage框架内部,还可以通过监听通知来清理缓存

  来到SDImageCache这个类中,可以看到它里面有一个- init方法。在这个方法中,通过注册通知来监听内存警告并移除数据:

SDWebImage框架重要的细节_第7张图片
在- init方法中用通知来监听内存警告的方法来清理数据.png

  除了在- init方法中可以处理内存警告之外,还有一个- initWithNamespace: diskCacheDirectory:方法,也是用注册通知的方式来监听内存警告并清理缓存的:

SDWebImage框架重要的细节_第8张图片
还是通过注册通知来监听内存警告.png

  5、对缓存文件的处理

  在《多线程技术的综合应用》这篇笔记中,当时我们实现缓存机制时,用的是一个可变字典(NSMutableDictionary)。那么,在SDWebImage框架中,它是怎么实现缓存的呢?可以来到SDWebImage处理缓存的类SDImageCache中看一下:

SDWebImage框架重要的细节_第9张图片
对缓存文件的处理.png

  从上面的图中我们可以看到,它用的是NSCache。NSCache是苹果提供的专门用来处理缓存的一个类,相比而言,比NSDictionary更专业。

  6、对图片类型的判断

  在上一篇笔记《SDWebImage的基本使用》中,我们知道如何使用这个框架来播放GIF图片了。那么,SDWebImage是如何分辨一张图片是JPEG还是GIF呢?要搞清楚这个问题,就需要看一下NSData+ImageContentType这个分类。

  在NSData+ImageContentType这个分类中,它有一个类方法+ sd_contentTypeForImageData:就是专门用来判断各种图片类型的。其主要思路是,拿到一张图片十六进制数据的第一个字节进行判断,然后再根据不同的结果返回图片的真实类型。只要是同一种类型的图片,它十六进制数据的第一个字节都是相同的。在Xcode中可以查看图片的十六进制形式,因此,也可以通过查看不同类型图片的十六进制编码来验证这一思路。具体的查看方式如下图所示:

SDWebImage框架重要的细节_第10张图片
以十六进制的形式查看一张图片.png

  SDWebImage就是运用同一种类型的图片,它十六进制数据的第一个字节编码是固定不变的这一特性来判断图片真实类型的。GIF图片的十六进制形式如下图所示:


GIF图片的十六进制形式.png

  JPEG图片十六进制数据的第一个字节是0xFF,PNG图片十六进制数据的第一个字节是0x89,GIF图片十六进制数据的第一个字节是0x47。

  7、网络请求超时的具体时间

  在下载网络图片的过程中,可能会碰到网速较慢,甚至是网络故障。这种情况下,很容易面临网络请求超时的状况。那么,在SDWebImage中,网络请求超时的时间设定是多少呢?要了解这个问题,就应该到处理网络下载的类中找答案。

  来到SDWebImageDownloader这个类中,还是在- init这个方法里,可以看到,downloadTimeout默认的值是15秒:

SDWebImage框架重要的细节_第11张图片
网络超时的时长设定.png

  也就是说,在SDWebImage框架中,网络请求超时的时长被设定为15秒


你可能感兴趣的:(iOS,SDWebImage)