1. 程式人生 > >SDWebImage源碼閱讀(五)SDImageCacheConfig/SDImageCache(下)

SDWebImage源碼閱讀(五)SDImageCacheConfig/SDImageCache(下)

繼承 evict spa 不同之處 warn .com 全面 ring ext

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

SDWebImage源碼閱讀(五)SDImageCacheConfig/SDImageCache(下)