4 SDWebImage(SDWebImage的实现机制)
主要功能:
提供UIImageView的一个分类,以支持网络图片的加载与缓存管理
一个异步的图片加载器
一个异步的内存+磁盘图片缓存
支持GIF图片
支持WebP图片
缓存
为了减少网络流量的消耗,我们都希望下载下来的图片缓存到本地,下次再去获取同一张图片时,可以直接从本地获取,而不再从远程服务器获取。这样做的另一个好处是提升了用户体验,用户第二次查看同一幅图片时,能快速从本地获取图片直接呈现给用户。
SDWebImage提供了对图片缓存的支持,而该功能是由SDImageCache类来完成的。该类负责处理内存缓存及一个可选的磁盘缓存。其中磁盘缓存的写操作是异步的,这样就不会对UI操作造成影响。
内存缓存与磁盘缓存
内存缓存的处理是使用NSCache对象来实现的。NSCache是一个类似于集合的容器。它存储key-value对,这一点类似于NSDictionary类。我们通常用使用缓存来临时存储短时间使用但创建昂贵的对象。重用这些对象可以优化性能,因为它们的值不需要重新计算。另外一方面,这些对象对于程序来说不是紧要的,在内存紧张时会被丢弃。
磁盘缓存的处理则是使用NSFileManager对象来实现的。图片存储的位置是位于Cache文件夹。另外,SDImageCache还定义了一个串行队列,来异步存储图片。
SDImageCache提供了大量方法来缓存、获取、移除及清空图片。而对于每个图片,为了方便地在内存或磁盘中对它进行这些操作,我们需要一个key值来索引它。在内存中,我们将其作为NSCache的key值,而在磁盘中,我们用这个key作为图片的文件名。对于一个远程服务器下载的图片,其url是作为这个key的最佳选择了。我们在后面会看到这个key值的重要性。
SDWebImage的主要任务就是图片的下载和缓存。为了支持这些操作,
它主要使用了以下知识点: dispatch_barrier_sync函数:该方法用于对操作设置屏幕,确保在执行完任务后才会执行后续操作。该方法常用于确保类的线程安全性操作。
NSMutableURLRequest:用于创建一个网络请求对象,我们可以根据需要来配置请求报头等信息。
框架SDWebimage的缓存机制
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 进行的操作,所以回主线程进行结果回调
7 notifyDelegate:
8 如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调imageCache:didFindImage:forKey:userInfo:进而回调展示图片。
9 如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调
10 imageCache:didNotFindImageForKey:userInfo:
11 共享或重新生成一个下载器SDWebImageDownloader 开始下载图片。
12 图片下载由NSURLConnection 来做,实现相关delegate 来判断图片下载中、下载完成和下载失败。
13 connection:didReceiveData: 中利用ImageIO 做了按图片下载进度加载效果。
14 connectionDidFinishLoading: 数据下载完成后交给SDWebImageDecoder 做图片解码处理。
15 图片解码处理在一个NSOperationQueue 完成,不会拖慢主线程UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。
16 在主线程notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo:回调给SDWebImageDownloader。
17 imageDownloader:didFinishWithImage: 回调给SDWebImageManager 告知图片下载完成。
18 通知所有的downloadDelegates 下载完成,回调给需要的地方展示图片。
19 将图片保存到SDImageCache 中,内存缓存和硬盘缓存同时保存。
20 写文件到硬盘在单独NSInvocationOperation 中完成,避免拖慢主线程。
21 如果是在iOS上运行,SDImageCache 在初始化的时候会注册notification 到UIApplicationDidReceiveMemoryWarningNotification 以及 UIApplicationWillTerminateNotification,在内存警告的时候清理内存图片缓存,应用结束的时候清理过期图片。
22 SDWebImagePrefetcher 可以预先下载图片,方便后续使用。
NSCache
特点: a> 线程安全的b> 当内存不足的时候,自动释放c> 缓存数量和缓存成本
区别NSMutableDictionary
1> 不能也不应该遍历 2> NSCache对key强引用,NSMutableDictionary对key进行copy
网友评论