對(duì)NSCache的一些理解...

對(duì)于NSCache的一些理解


對(duì)于有一定開發(fā)經(jīng)驗(yàn)的iOS攻城獅來說,我們在對(duì)一個(gè)APP數(shù)據(jù)做存儲(chǔ)和內(nèi)存優(yōu)化的時(shí)候,不可避免的需要對(duì)緩存做相應(yīng)的處理,而且緩存處理的優(yōu)劣,往往也是決定一個(gè)APP能否長線發(fā)展的重要因素之一,今天就來說一下經(jīng)常容易被我們忽略的一個(gè)蘋果官方提供的一套緩存機(jī)制--->NSCache


什么是NSCache?

1. NSCache蘋果提供的一套緩存機(jī)制

主要作用于內(nèi)存緩存的管理方面;
在沒有引入NSCache之前,我們要管理緩存,都是使用的NSMutableDictionary來管理,如:

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

然而,使用NSMutableDictionary來管理緩存是有些不妥的, 知道多線程操作原理的開發(fā)者都明白, NSMutableDictionary在線程方面來說是不安全,這也是蘋果官方文檔明確說明了的,而如果使用的是NSCache,那就不會(huì)出現(xiàn)這些問題.所以接下來我們先看看二者的區(qū)別:

&1 NSCache和NSMutableDictionary的相同點(diǎn)與區(qū)別:

相同點(diǎn):
NSCache和NSMutableDictionary功能用法基本是相同的。

區(qū)別:

  1. NSCache是線程安全的售碳,NSMutableDictionary線程不安全
    NSCache線程是安全的稀蟋,Mutable開發(fā)的類一般都是線程不安全的
  2. 當(dāng)內(nèi)存不足時(shí)NSCache會(huì)自動(dòng)釋放內(nèi)存(所以從緩存中取數(shù)據(jù)的時(shí)候總要判斷是否為空)
  3. NSCache可以指定緩存的限額,當(dāng)緩存超出限額自動(dòng)釋放內(nèi)存
    緩存限額:
  1. 緩存數(shù)量
    @property NSUInteger countLimit;
  2. 緩存成本
    @property NSUInteger totalCostLimit;
  1. 蘋果給NSCache封裝了更多的方法和屬性,比NSMutableDictionary的功能要強(qiáng)大很多

2.代碼演示:

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

#import "ViewController.h"

@interface ViewController () <NSCacheDelegate>

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

@implementation ViewController
- (NSCache *)cache {
if (_cache == nil) {
    _cache = [[NSCache alloc] init];
    // 緩存中總共可以存儲(chǔ)多少條
    _cache.countLimit = 5;
    // 緩存的數(shù)據(jù)總量為多少
    _cache.totalCostLimit = 1024 * 5;
}
return _cache;
}

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

  //添加緩存數(shù)據(jù)
   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]);
   }

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

}

控制臺(tái)輸出結(jié)果為:

輸出結(jié)果

**通過輸出結(jié)果可以看出: **

1.當(dāng)我們使用NSCache來創(chuàng)建緩存池的時(shí)候,我們可以很靈活的設(shè)置緩存的限額,
2.當(dāng)程序中的個(gè)數(shù)超過我們的限額的時(shí)候,會(huì)先移除最先創(chuàng)建的
3.如果已經(jīng)移除了,那么當(dāng)我們輸出緩存中的數(shù)據(jù)的時(shí)候,就只剩下后面創(chuàng)建的數(shù)據(jù)了;

3. 演示NSCache的代理方法

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

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

輸出結(jié)果為:


輸出結(jié)果
輸出結(jié)果

通過結(jié)果可以看出:
NSCache的功能要比NSMutableDictionary的功能要強(qiáng)大很多很多;

4.當(dāng)遇到內(nèi)存警告的時(shí)候,

代碼演示:

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

控制臺(tái)輸出結(jié)果:

收到內(nèi)存警告
收到內(nèi)存警告

通過結(jié)果可以看出:
當(dāng)收到內(nèi)存警告之后,清除數(shù)據(jù)之后,NSCache緩存池中所有的數(shù)據(jù)都會(huì)為空!

5.當(dāng)收到內(nèi)存警告,調(diào)用removeAllObjects 之后,無法再次往緩存池中添加數(shù)據(jù)

代碼演示:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    //當(dāng)收到內(nèi)存警告褒搔,調(diào)用removeAllObjects 之后,無法再次往緩存中添加數(shù)據(jù)
    [self.cache removeAllObjects];
    //輸出緩存中的數(shù)據(jù)
    for (int i = 0; i < 10; i++) {
        NSLog(@"%@",[self.cache objectForKey:[NSString stringWithFormat:@"h%d",i]]);
    }
}

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

}

控制臺(tái)輸出結(jié)果為:


輸出結(jié)果
輸出結(jié)果

通過輸出結(jié)果,我們可以看出:
當(dāng)收到內(nèi)存警告喷面,而我們又調(diào)用removeAllObjects 之后星瘾,則無法再次往緩存中添加數(shù)據(jù);

更多詳情可以查看我的Github項(xiàng)目:
https://github.com/DXSmile/NSCache-some-understanding..git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惧辈,隨后出現(xiàn)的幾起案子琳状,更是在濱河造成了極大的恐慌,老刑警劉巖盒齿,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件念逞,死亡現(xiàn)場離奇詭異困食,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)翎承,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門硕盹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人审洞,你說我怎么就攤上這事莱睁。” “怎么了芒澜?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長创淡。 經(jīng)常有香客問我痴晦,道長,這世上最難降的妖魔是什么琳彩? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任誊酌,我火速辦了婚禮,結(jié)果婚禮上露乏,老公的妹妹穿的比我還像新娘碧浊。我一直安慰自己,他們只是感情好瘟仿,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布箱锐。 她就那樣靜靜地躺著,像睡著了一般劳较。 火紅的嫁衣襯著肌膚如雪驹止。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天观蜗,我揣著相機(jī)與錄音臊恋,去河邊找鬼。 笑死墓捻,一個(gè)胖子當(dāng)著我的面吹牛抖仅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砖第,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼撤卢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了厂画?” 一聲冷哼從身側(cè)響起凸丸,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袱院,沒想到半個(gè)月后屎慢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞭稼,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年腻惠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了环肘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡集灌,死狀恐怖悔雹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情欣喧,我是刑警寧澤腌零,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站唆阿,受9級(jí)特大地震影響益涧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驯鳖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一闲询、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浅辙,春花似錦扭弧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至氨淌,卻和暖如春泊愧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盛正。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工删咱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人豪筝。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓痰滋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親续崖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子敲街,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容