在上篇中已经了解分析了 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