NSCache的一些理解

對於NSCache的一些理解


對於有必定開發經驗的iOS攻城獅來講,咱們在對一個APP數據作存儲和內存優化的時候,不可避免的須要對緩存作相應的處理,並且緩存處理的優劣,每每也是決定一個APP可否長線發展的重要因素之一,今天就來講一下常常容易被咱們忽略的一個蘋果官方提供的一套緩存機制--->NSCachegit


什麼是NSCache?

1. NSCache蘋果提供的一套緩存機制

主要做用於內存緩存的管理方面; 在沒有引入NSCache以前,咱們要管理緩存,都是使用的NSMutableDictionary來管理,如:github

// 定義下載操做緩存池
@property (nonatomic, strong) NSMutableDictionary *operationCache;
// 定義圖片緩存池
@property (nonatomic, strong) NSMutableDictionary *imageCache;

然而,使用NSMutableDictionary來管理緩存是有些不妥的, 知道多線程操做原理的開發者都明白, NSMutableDictionary在線程方面來講是不安全,這也是蘋果官方文檔明確說明了的,而若是使用的是NSCache,那就不會出現這些問題.因此接下來咱們先看看兩者的區別:緩存

&1 NSCache和NSMutableDictionary的相同點與區別:

相同點: NSCache和NSMutableDictionary功能用法基本是相同的。安全

區別:多線程

  1. NSCache是線程安全的,NSMutableDictionary線程不安全 NSCache線程是安全的,Mutable開發的類通常都是線程不安全的
  2. 當內存不足時NSCache會自動釋放內存(因此從緩存中取數據的時候總要判斷是否爲空)
  3. NSCache能夠指定緩存的限額,當緩存超出限額自動釋放內存 緩存限額:
  1. 緩存數量 @property NSUInteger countLimit;
  2. 緩存成本 @property NSUInteger totalCostLimit;
  1. 蘋果給NSCache封裝了更多的方法和屬性,比NSMutableDictionary的功能要強大不少

2.代碼演示:

先定義緩存池,並懶加載初始化:優化

#import "ViewController.h"

@interface ViewController () <NSCacheDelegate>

// 定義緩存池
@property (nonatomic, strong) NSCache *cache;
@end

@implementation ViewController
- (NSCache *)cache {
if (_cache == nil) {
    _cache = [[NSCache alloc] init];
    // 緩存中總共能夠存儲多少條
    _cache.countLimit = 5;
    // 緩存的數據總量爲多少
    _cache.totalCostLimit = 1024 * 5;
}
return _cache;
}

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.

  //添加緩存數據
   for (int i = 0; i < 10; i++) {
    [self.cache setObject:[NSString stringWithFormat:@"hello %d",i] forKey:[NSString stringWithFormat:@"h%d",i]];
    NSLog(@"添加 %@",[NSString stringWithFormat:@"hello %d",i]);
   }

  //輸出緩存中的數據
   for (int i = 0; i < 10; i++) {
    NSLog(@"%@",[self.cache objectForKey:[NSString stringWithFormat:@"h%d",i]]);
   }

}

控制檯輸出結果爲: 控制檯輸出結果atom

**經過輸出結果能夠看出: **線程

1.當咱們使用NSCache來建立緩存池的時候,咱們能夠很靈活的設置緩存的限額, 2.當程序中的個數超過咱們的限額的時候,會先移除最早建立的 3.若是已經移除了,那麼當咱們輸出緩存中的數據的時候,就只剩下後面建立的數據了;代理

3. 演示NSCache的代理方法

先設置代理對象: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //設置NSCache的代理 self.cache.delegate = self; 調用代理方法: 這裏我僅用一個方法來演示:code

//當緩存被移除的時候執行
         - (void)cache:(NSCache *)cache willEvictObject:(id)obj{
	    NSLog(@"緩存移除  %@",obj);
       }

輸出結果爲: 輸出結果

經過結果能夠看出: NSCache的功能要比NSMutableDictionary的功能要強大不少不少;

4.當遇到內存警告的時候,

代碼演示:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    //當收到內存警告,清除內存
    [self.cache removeAllObjects];
    //輸出緩存中的數據
    for (int i = 0; i < 10; i++) {
        NSLog(@"%@",[self.cache objectForKey:[NSString stringWithFormat:@"h%d",i]]);
    }
}

控制檯輸出結果: 收到內存警告 經過結果能夠看出: 當收到內存警告以後,清除數據以後,NSCache緩存池中全部的數據都會爲空!

5.當收到內存警告,調用removeAllObjects 以後,沒法再次往緩存池中添加數據

代碼演示:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    //當收到內存警告,調用removeAllObjects 以後,沒法再次往緩存中添加數據
    [self.cache removeAllObjects];
    //輸出緩存中的數據
    for (int i = 0; i < 10; i++) {
        NSLog(@"%@",[self.cache objectForKey:[NSString stringWithFormat:@"h%d",i]]);
    }
}

// 觸摸事件, 以便驗證添加數據
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.cache removeAllObjects];
    
    //添加緩存數據
    for (int i = 0; i < 10; i++) {
        [self.cache setObject:[NSString stringWithFormat:@"hello %d",i] forKey:[NSString stringWithFormat:@"h%d",i]];
//        NSLog(@"添加 %@",[NSString stringWithFormat:@"hello %d",i]);
    }
    
    //輸出緩存中的數據
    for (int i = 0; i < 10; i++) {
        NSLog(@"%@",[self.cache objectForKey:[NSString stringWithFormat:@"h%d",i]]);
    }

}

控制檯輸出結果爲: 輸出結果

經過輸出結果,咱們能夠看出: 當收到內存警告,而咱們又調用removeAllObjects 以後,則沒法再次往緩存中添加數據;

更多詳情能夠查看個人Github項目: https://github.com/DXSmile/NSCache-some-understanding..git

相關文章
相關標籤/搜索