SDWebImage源码阅读(五)SDImageCacheConfig/SDImageCache(下)

  在上篇中已经了解分析了 SDImageCache.h 文件中所有的方法和属性。大概对 SDImageCache 能实现的功能已经有了全面的认识。在这篇则着重学习研究这些功能的实现过程和实现原理。

  SDImageCache  是 SDWebImage 里面用来做缓存的类,虽然只是针对的图片的缓存,但是其实在 iOS 开发甚至在程序开发中,缓存类对缓存文件的类型区别而要单独针对文件类型做处理的需要并不多,不管是图片的缓存还是别的类型文件的缓存,它们在缓存原理上是基本一致的。通过对 SDImageCache 针对图片的缓存处理的实现的学习,在以后有开发需求要做别的类型文件的缓存处理的时候,都可以对其模仿和学习,创建类似的缓存管理类。

  下面开始学习 SDImageCache.m 的代码:

  首先是在 SDImageCache.m 内部嵌套定义了一个继承自 NSCache 的类 AutoPurgeCache。

  AutoPurgeCache 类 .h/.m 全部的内容:

 1 // See https://github.com/rs/SDWebImage/pull/1141 for discussion
 2 @interface AutoPurgeCache : NSCache
 3 @end
 4
 5 @implementation AutoPurgeCache
 6
 7 - (nonnull instancetype)init {
 8     self = [super init];
 9     if (self) {
10 #if SD_UIKIT
11         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
12 #endif
13     }
14     return self;
15 }
16
17 - (void)dealloc {
18 #if SD_UIKIT
19     [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
20 #endif
21 }
22
23 @end

   如果是当前开发平台包含 UIKit框架,在 AutoPurgeCache 类的 init 方法里面添加一个名字为

UIApplicationDidReceiveMemoryWarningNotification 的通知,接收到通知的时候执行

removeAllObjects 方法,在该类的 dealloc  方法里面,移除名字是

UIApplicationDidReceiveMemoryWarningNotification 的通知。

  UIApplicationDidReceiveMemoryWarningNotification 是定义在 UIApplication.h 里面的一个不可变的字符串常量:

1 UIKIT_EXTERN NSNotificationName const UIApplicationDidReceiveMemoryWarningNotification;

2 typedef NSString *NSNotificationName NS_EXTENSIBLE_STRING_ENUM;

  当应用程序接收到内存警告是会发送该通知,让应用程序清理内存。

  接下来学习一下 NSCache 这个类:

  NSCache 是包含在 Foundation  框架里面的一个类,它的 .h 全部代码才 40 多行:

 1 #import <Foundation/NSObject.h>
 2
 3 @class NSString;
 4 @protocol NSCacheDelegate;
 5
 6 NS_ASSUME_NONNULL_BEGIN
 7
 8 NS_CLASS_AVAILABLE(10_6, 4_0)
 9 @interface NSCache <KeyType, ObjectType> : NSObject {
10 @private
11     id _delegate;
12     void *_private[5];
13     void *_reserved;
14 }
15
16 @property (copy) NSString *name;
17
18 @property (nullable, assign) id<NSCacheDelegate> delegate;
19
20 - (nullable ObjectType)objectForKey:(KeyType)key;
21 - (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost
22 - (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
23 - (void)removeObjectForKey:(KeyType)key;
24
25 - (void)removeAllObjects;
26
27 @property NSUInteger totalCostLimit;    // limits are imprecise/not strict
28 @property NSUInteger countLimit;    // limits are imprecise/not strict
29 @property BOOL evictsObjectsWithDiscardedContent;
30
31 @end
32
33 @protocol NSCacheDelegate <NSObject>
34 @optional
35 - (void)cache:(NSCache *)cache willEvictObject:(id)obj;
36 @end
37
38 NS_ASSUME_NONNULL_END

  NSCache 是系统提供的一种类似于集合(NSMutableDictionary)的缓存,它与集合不同之处是:

  1.NSCache 具有自动删除的功能,以减少系统占用的内存。

  2.NSCache 是线程安全的,不需要加线程锁。

  3.键对象不会像 NSMutableDictionary 中那样被复制。(键不需要实现 NSCopying 协议)

参考链接:http://www.jianshu.com/p/a33d5abf686b

http://www.jianshu.com/p/5e69e211b161

时间: 2024-10-18 20:08:06

SDWebImage源码阅读(五)SDImageCacheConfig/SDImageCache(下)的相关文章

【原】SDWebImage源码阅读(五)

[原]SDWebImage源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 前面的代码并没有特意去讲SDWebImage的缓存机制,主要是想单独开一章节专门讲解缓存.之前我们也遇到一些缓存的属性和方法,比如storeImage.queryDiskCacheForKey.memCache等等. SDWebImage的缓存分为两个部分,一个内存缓存,使用NSCache实现,另一个就是硬盘缓存(disk),使用NSFileManager实现. 不过这么多函数,

【原】SDWebImage源码阅读(二)

[原]SDWebImage源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 解决上一篇遗留的坑 上一篇中对sd_setImageWithURL函数简单分析了一下,还留了一些坑.不过因为我们现在对这个函数有一个大概框架了,我们就按顺序一个个来解决. 首先是这一句代码: objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 就是给UIImageVi

【原】SDWebImage源码阅读(三)

[原]SDWebImage源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1.SDWebImageDownloader中的downloadImageWithURL 我们来到SDWebImageDownloader.m文件中,找到downloadImageWithURL函数.发现代码不是很长,那就一行行读.毕竟这个函数大概做什么我们是知道的.这个函数大概就是创建了一个SDWebImageSownloader的异步下载器,根据给定的URL下载image. 先映入眼帘的

SDWebImage源码阅读-第三篇

这一篇讲讲不常用的一些方法. 1 sd_setImageWithPreviousCachedImageWithURL: placeholderImage: options: progress: completed: 取得上次缓存的图片,然后作为占位图的参数再次进行一次图片设置. - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options

SDWebImage源码阅读(四)SDWebImageDecoder

一般我们都是使用: 1 + (nullable UIImage *)imageNamed:(NSString *)name; // load from main bundle 和: 1 + (nullable UIImage *)imageWithContentsOfFile:(NSString *)path; 两种方式加载图片,它们两个的区别在SDWebImage源码阅读前的准备(三)UIImage.h 里面的 "(六):加载和创建UIImage 的类方法和实例方法:"部分有详细的介

【原】SDWebImage源码阅读(一)

[原]SDWebImage源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 一直没有系统地读过整套源码,就感觉像一直看零碎的知识点,没有系统读过一本专业经典书籍一样,会有点发虚,感觉知识体系不健全!废话少说,这次我决定好好阅读下SDWebImage的源码,我的阅读方式,是带着问题去阅读源码,然后强迫自己写博客. 2. SDWebImage是做什么的? 既然是要带着问题读,那么第一个问题就来了,SDWebImage是做什么的?SDWebImage是一个开源

SDWebImage源码阅读(二)NSData+ImageContentType

NSData+ImageContentType 是NSData 的分类(Category). 创建分类的步骤: 在Xcode 工程页面,按command + N ,在iOS -> Source 选择Objective-C File ,点击Next ,File Type 选择 Category ,file 框里输入分类名字,Calss 为要添加分类的类,可以是系统的类也可以是自定义的类,当然这里出现的主要是系统的类. 分类的描述: 无论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎

SDWebImage源码阅读(三)UIImage+GIF

UIImage+GIF 是UIImage 类的一个GIF 分类,在之前的版本里面这个分类是用了处理GIF 动态图片的但是会有内存暴增的bug.在当前 '4.0.0-beta2' 的版本里GIF 动态图片处理放在了UIImage+MultiFormat  这个分类里面,而当前这个GIF 的分类的功能只是将动态图片作为静态图片来处理,如果是静态图片的NSData 数据则转化为静态UIImage 直接返回,如果是动态图片的NSData 数据,则把图像的第1帧图像转换化为静态UIImage 返回. 首先

SDWebImage源码阅读(十五)UIView+WebCacheOperation

这个分类主要用来对 UIView 的图像下载操作添加.取消和移除. .h 1 * Set the image load operation (storage in a UIView based dictionary) 2 * 3 * @param operation the operation 4 * @param key key for storing the operation 5 */ 6 - (void)sd_setImageLoadOperation:(nullable id)oper