iOS技術(shù)文檔No.26 Foundation_NSCache緩存

NSURLCache
NSURLCache 為您的應(yīng)用的 URL 請(qǐng)求提供了內(nèi)存中以及磁盤上的綜合緩存機(jī)制幢泼。 作為基礎(chǔ)類庫(kù) URL 加載系統(tǒng) 的一部分,任何通過 NSURLConnection 加載的請(qǐng)求都將被 NSURLCache 處理根竿。
網(wǎng)絡(luò)緩存減少了需要向服務(wù)器發(fā)送請(qǐng)求的次數(shù),同時(shí)也提升了離線或在低速網(wǎng)絡(luò)中使用應(yīng)用的體驗(yàn)。
當(dāng)一個(gè)請(qǐng)求完成下載來自服務(wù)器的回應(yīng)忿偷,一個(gè)緩存的回應(yīng)將在本地保存。下一次同一個(gè)請(qǐng)求再發(fā)起時(shí)臊泌,本地保存的回應(yīng)就會(huì)馬上返回鲤桥,不需要連接服務(wù)器。NSURLCache 會(huì) 自動(dòng) 且 透明 地返回回應(yīng)渠概。
為了好好利用 NSURLCache茶凳,你需要初始化并設(shè)置一個(gè)共享的 URL 緩存。在 iOS 中這項(xiàng)工作需要在 -application:didFinishLaunchingWithOptions: 完成播揪,而 OS X 中是在 –applicationDidFinishLaunching::

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil]; [NSURLCache setSharedURLCache:URLCache];}
    1
    2
    3
    4
    5
    6
    7
    8

1
2
3
4
5
6
7
8

緩存策略由請(qǐng)求(客戶端)和回應(yīng)(服務(wù)端)分別指定贮喧。理解這些策略以及它們?nèi)绾蜗嗷ビ绊懀菫槟膽?yīng)用程序找到最佳行為的關(guān)鍵猪狈。
NSURLRequestCachePolicy 緩存策略
NSURLRequest 有個(gè) cachePolicy 屬性箱沦,它根據(jù)以下常量指定了請(qǐng)求的緩存行為:
NSURLRequestUseProtocolCachePolicy: 對(duì)特定的 URL 請(qǐng)求使用網(wǎng)絡(luò)協(xié)議中實(shí)現(xiàn)的緩存邏輯。這是默認(rèn)的策略雇庙。 NSURLRequestReloadIgnoringLocalCacheData:數(shù)據(jù)需要從原始地址加載谓形。不使用現(xiàn)有緩存。 NSURLRequestReloadIgnoringLocalAndRemoteCacheData:不僅忽略本地緩存疆前,同時(shí)也忽略代理服務(wù)器或其他中間介質(zhì)目前已有的寒跳、協(xié)議允許的緩存。 NSURLRequestReturnCacheDataElseLoad:無(wú)論緩存是否過期竹椒,先使用本地緩存數(shù)據(jù)童太。如果緩存中沒有請(qǐng)求所對(duì)應(yīng)的數(shù)據(jù),那么從原始地址加載數(shù)據(jù)。 NSURLRequestReturnCacheDataDontLoad:無(wú)論緩存是否過期书释,先使用本地緩存數(shù)據(jù)翘贮。如果緩存中沒有請(qǐng)求所對(duì)應(yīng)的數(shù)據(jù),那么放棄從原始地址加載數(shù)據(jù)征冷,請(qǐng)求視為失斣裣ァ(即:“離線”模式)。 NSURLRequestReloadRevalidatingCacheData:從原始地址確認(rèn)緩存數(shù)據(jù)的合法性后, 必須得得到服務(wù)端確認(rèn)有效才使用(貌似是NSURLRequestUseProtocolCachePolicy 中的一種情況)检激,緩存數(shù)據(jù)就可以使用肴捉,否則從原始地址加載。
注: 1.URL Loading System默認(rèn)只支持如下5中協(xié)議: 其中只有http://和https://才有緩存策略. (1) http:// (2) https:// (3) ftp:// (4) file:// (5) data://
2.NSURLRequestReloadIgnoringLocalAndRemoteCacheData 和 NSURLRequestReloadRevalidatingCacheData 根本沒有實(shí)現(xiàn)叔收!
關(guān)于NSURLRequestCachePolicy齿穗,以下才是你實(shí)際需要了解的東西:

這里寫圖片描述

HTTP 緩存語(yǔ)義
因?yàn)?NSURLConnection 被設(shè)計(jì)成支持多種協(xié)議——包括 FTP、HTTP饺律、HTTPS——所以 URL 加載系統(tǒng)用一種協(xié)議無(wú)關(guān)的方式指定緩存窃页。為了本文的目的,緩存用術(shù)語(yǔ) HTTP 語(yǔ)義來解釋复濒。
HTTP 請(qǐng)求和回應(yīng)用 headers 來交換元數(shù)據(jù)脖卖,如字符編碼、MIME 類型和緩存指令等巧颈。
Request Cache Headers
在默認(rèn)情況下畦木,NSURLRequest 會(huì)用當(dāng)前時(shí)間決定是否返回緩存的數(shù)據(jù)。為了更精確地控制砸泛,允許使用以下請(qǐng)求頭:
If-Modified-Since - 這個(gè)請(qǐng)求頭與 Last-Modified 回應(yīng)頭相對(duì)應(yīng)十籍。把這個(gè)值設(shè)為同一終端最后一次請(qǐng)求時(shí)返回的 Last-Modified 字段的值。 If-None-Match - 這個(gè)請(qǐng)求頭與與 Etag 回應(yīng)頭相對(duì)應(yīng)唇礁。使用同一終端最后一次請(qǐng)求的 Etag 值勾栗。
Response Cache Headers
NSHTTPURLResponse 包含多個(gè) HTTP 頭,當(dāng)然也包括以下指令來說明回應(yīng)應(yīng)當(dāng)如何緩存:
Cache-Control - 這個(gè)頭必須由服務(wù)器端指定以開啟客戶端的 HTTP 緩存功能盏筐。這個(gè)頭的值可能包含 max-age(緩存多久)围俘,是公共 public 還是私有 private,或者不緩存 no-cache 等信息琢融。詳情請(qǐng)參閱 Cache-Control section of RFC 2616楷拳。 除了 Cache-Control 以外,服務(wù)器也可能發(fā)送一些附加的頭用于根據(jù)需要有條件地請(qǐng)求:
Last-Modified - 這個(gè)頭的值表明所請(qǐng)求的資源上次修改的時(shí)間吏奸。例如,一個(gè)客戶端請(qǐng)求最近照片的時(shí)間線陶耍,/photos/timeline奋蔚,Last-Modified 的值可以是最近一張照片的拍攝時(shí)間。 Etag - 這是 “entity tag” 的縮寫,它是一個(gè)表示所請(qǐng)求資源的內(nèi)容的標(biāo)識(shí)符泊碑。在實(shí)踐中坤按,Etag 的值可以是類似于資源的 MD5 之類的東西。這對(duì)于那些動(dòng)態(tài)生成的馒过、可能沒有明顯的 Last-Modified 值的資源非常有用臭脓。
NSURLConnectionDelegate
一旦收到了服務(wù)器的回應(yīng),NSURLConnection 的代理就有機(jī)會(huì)在 -connection:willCacheResponse: 中指定緩存數(shù)據(jù)腹忽。
NSCachedURLResponse 是個(gè)包含 NSURLResponse 以及它對(duì)應(yīng)的緩存中的 NSData 的類来累。
在 -connection:willCacheResponse: 中,cachedResponse 對(duì)象會(huì)根據(jù) URL 連接返回的結(jié)果自動(dòng)創(chuàng)建窘奏。因?yàn)?NSCachedURLResponse 沒有可變部分嘹锁,為了改變 cachedResponse 中的值必須構(gòu)造一個(gè)新的對(duì)象,把改變過的值傳入 –initWithResponse:data:userInfo:storagePolicy:着裹,例如:

  • (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{ NSMutableDictionary *mutableUserInfo = [[cachedResponse userInfo] mutableCopy]; NSMutableData *mutableData = [[cachedResponse data] mutableCopy]; NSURLCacheStoragePolicy storagePolicy = NSURLCacheStorageAllowedInMemoryOnly; // ... return [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response] data:mutableData userInfo:mutableUserInfo storagePolicy:storagePolicy];}
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

1
2
3
4
5
6
7
8
9
10
11
12
13
14

如果 -connection:willCacheResponse: 返回 nil领猾,回應(yīng)將不會(huì)緩存。

  • (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{ return nil;}
    1
    2
    3
    4
    5

1
2
3
4
5

如果不實(shí)現(xiàn)此方法骇扇,NSURLConnection 就簡(jiǎn)單地使用本來要傳入 -connection:willCacheResponse: 的那個(gè)緩存對(duì)象摔竿,所以除非你需要改變一些值或者阻止緩存,否則這個(gè)代理方法不必實(shí)現(xiàn)少孝。
NSURLCache & NSCachedURLResponse常用方法
NSURLCache
1.初始化相關(guān)的幾個(gè)方法:sharedURLCache继低;setSharedURLCache;initWithMemoryCapacity sharedURLCache方法返回一個(gè)NSURLCache實(shí)例韭山。 默認(rèn)情況下郁季,內(nèi)存是4M,4* 1024 * 1024钱磅;Disk為20M梦裂,20 * 1024 * 1024;路徑在(NSHomeDirectory)/Library/Caches/(current application name, [[NSProcessInfo processInfo] processName]) setSharedURLCache可以通過這個(gè)方法來改變默認(rèn)的NSURLCache盖淡。通過initWithMemoryCapacity來定制自己的NSURLCache年柠。
2.cache使用相關(guān)的幾個(gè)方法:cachedResponseForRequest;storeCachedResponse褪迟;removeCachedResponseForRequest; removeAllCachedResponses - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; 如果對(duì)應(yīng)的NSURLRequest沒有cached的response那么返回nil - (void)storeCachedResponse:(NSCachedURLResponse )cachedResponse forRequest:(NSURLRequest)request; 為特定的NSURLRequest做cache - (void)removeCachedResponseForRequest:(NSURLRequest *)request; 移除特定NSURLRequest的cache - (void)removeAllCachedResponses; 移除所有的cache
3.property方法 - (NSUInteger)memoryCapacity; - (NSUInteger)diskCapacity; - (void)setMemoryCapacity:(NSUInteger)memoryCapacity; 可能會(huì)導(dǎo)致內(nèi)存中的內(nèi)存被截?cái)?- (void)setDiskCapacity:(NSUInteger)diskCapacity; - (NSUInteger)currentMemoryUsage; - (NSUInteger)currentDiskUsage;
4.Misc a. NSURLCache在每個(gè)UIWebView的的NSURLRequest請(qǐng)求中都會(huì)被調(diào)用味赃。 b. ios設(shè)備上NSURLCache默認(rèn)只能進(jìn)行內(nèi)存緩存掀抹。可以通過子類化NSURLCache來實(shí)現(xiàn)自定義的版本從而實(shí)現(xiàn)在DISK上緩存內(nèi)容心俗。 c. 需要重寫cachedResponseForRequest傲武,這個(gè)會(huì)在請(qǐng)求發(fā)送前會(huì)被調(diào)用蓉驹,從中我們可以判定是否針對(duì)此NSURLRequest返回本地?cái)?shù)據(jù)。 d. 如果本地沒有緩存就調(diào)用下面這條語(yǔ)句:return [super cachedResponseForRequest:request];
NSCachedURLResponse
包裝了一下系統(tǒng)緩存機(jī)制的對(duì)象揪利,保持了緩存對(duì)象的個(gè)性和特性态兴。 1.NSURLCacheStoragePolicy 緩存策略有三種 enum { NSURLCacheStorageAllowed, NSURLCacheStorageAllowedInMemoryOnly, NSURLCacheStorageNotAllowed, }; 默認(rèn)是第一種。不過在iOS的上官方文檔上有這么一個(gè)解釋: Important: iOS ignores this cache policy, and instead treats it asNSURLCacheStorageAllowedInMemoryOnly. 也就是說iOS上只有內(nèi)存緩存疟位,沒有磁盤緩存瞻润。
2.構(gòu)造方法 - (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data; - (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data userInfo:(NSDictionary *)userInfo storagePolicy:(NSURLCacheStoragePolicy)storagePolicy;
3.Open API - (NSURLResponse *)response; - (NSData *)data; - (NSDictionary *)userInfo; - (NSURLCacheStoragePolicy)storagePolicy;
注意事項(xiàng)
正如它那個(gè)毫無(wú)關(guān)系但是名字相近的小伙伴 NSCache 一樣,NSURLCache 也是有一些特別的甜刻。
Peter Steinberger 關(guān)于這個(gè)主題寫了一篇優(yōu)秀的文章绍撞,在深入研究?jī)?nèi)部細(xì)節(jié)后實(shí)現(xiàn)他自己的 NSURLCache 子類。NSURLCache 提醒著我們熟悉我們正在操作的系統(tǒng)是多么地重要罢吃。
Daniel Pasco 在 Black Pixel 上的另一篇文章 描述了一些與服務(wù)器通信時(shí)不設(shè)置緩存頭的意外的默認(rèn)行為楚午。
無(wú)數(shù)開發(fā)者嘗試自己做一個(gè)簡(jiǎn)陋而脆弱的系統(tǒng)來實(shí)現(xiàn)網(wǎng)絡(luò)緩存的功能,殊不知 NSURLCache 只要兩行代碼就能搞定且好上100倍尿招。甚至更多開發(fā)者根本不知道網(wǎng)絡(luò)緩存的好處矾柜,也從未嘗試過,導(dǎo)致他們的應(yīng)用向服務(wù)器作了無(wú)數(shù)不必要的網(wǎng)絡(luò)請(qǐng)求就谜。
所以如果你想看到世界的變化怪蔑,你想確保你有程序總以正確的方式開啟,在 -application:didFinishLaunchingWithOptions: 設(shè)置一個(gè)共享的 NSURLCache 吧丧荐。NSCache是系統(tǒng)提供的一種類似于集合(NSMutableDictionary)的緩存缆瓣,它與集合的不同如下:

  1. NSCache具有自動(dòng)刪除的功能,以減少系統(tǒng)占用的內(nèi)存虹统;

  2. NSCache是線程安全的弓坞,不需要加線程鎖;

  3. 鍵對(duì)象不會(huì)像 NSMutableDictionary 中那樣被復(fù)制车荔。(鍵不需要實(shí)現(xiàn) NSCopying 協(xié)議)渡冻。

NSCache的屬性以及方法介紹:

@property NSUInteger totalCostLimit;

設(shè)置緩存占用的內(nèi)存大小,并不是一個(gè)嚴(yán)格的限制忧便,當(dāng)總數(shù)超過了totalCostLimit設(shè)定的值族吻,系統(tǒng)會(huì)清除一部分緩存,直至總消耗低于totalCostLimit的值珠增。

@property NSUInteger countLimit;

設(shè)置緩存對(duì)象的大小超歌,這也不是一個(gè)嚴(yán)格的限制。

- (id)objectForKey:(id)key;

獲取緩存對(duì)象蒂教,基于key-value對(duì)

- (void)setObject:(id)obj forKey:(id)key; // 0 cost

存儲(chǔ)緩存對(duì)象巍举,考慮緩存的限制屬性;

- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;

存儲(chǔ)緩存對(duì)象凝垛,cost是提前知道該緩存對(duì)象占用的字節(jié)數(shù)懊悯,也會(huì)考慮緩存的限制屬性简烘,建議直接使用

- (void)setObject:(id)obj forKey:(id)key;

NSCacheDelegate代理

代理屬性聲明如下:

@property (assign) id<NSCacheDelegate>delegate;

實(shí)現(xiàn)了NSCacheDelegate代理的對(duì)象,在緩存對(duì)象即將被清理的時(shí)候定枷,系統(tǒng)回調(diào)代理方法如下:

- (void)cache:(NSCache *)cache willEvictObject:(id)obj;

第一個(gè)參數(shù)是當(dāng)前緩存(NSCache),不要修改該對(duì)象届氢;

第二個(gè)參數(shù)是當(dāng)前將要被清理的對(duì)象欠窒,如果需要存儲(chǔ)該對(duì)象,可以在此操作(存入Sqlite or CoreData);

該代理方法的調(diào)用會(huì)在緩存對(duì)象即將被清理的時(shí)候調(diào)用退子,如下場(chǎng)景會(huì)調(diào)用:

1.  - (void)removeObjectForKey:(id)key; 手動(dòng)刪除對(duì)象岖妄;

2.  緩存對(duì)象超過了NSCache的屬性限制;(countLimit 和 totalCostLimit )

3.  App進(jìn)入后臺(tái)會(huì)調(diào)用寂祥;

4.  系統(tǒng)發(fā)出內(nèi)存警告荐虐;

NSDiscardableContent協(xié)議

NSDiscardableContent是一個(gè)協(xié)議,實(shí)現(xiàn)這個(gè)協(xié)議的目的是為了讓我們的對(duì)象在不被使用時(shí)丸凭,可以將其丟棄福扬,以讓程序占用更少的內(nèi)存。

一個(gè)NSDiscardableContent對(duì)象的生命周期依賴于一個(gè)“counter”變量惜犀。一個(gè)NSDiscardableContent對(duì)象實(shí)際是一個(gè)可清理內(nèi)存塊铛碑,這個(gè)內(nèi)存記錄了對(duì)象當(dāng)前是否被其它對(duì)象使用。如果這塊內(nèi)存正在被讀取虽界,或者仍然被需要汽烦,則它的counter變量是大于或等于1的;當(dāng)它不再被使用時(shí)莉御,就可以丟棄撇吞,此時(shí)counter變量將等于0。當(dāng)counter變量等于0時(shí)礁叔,如果當(dāng)前時(shí)間點(diǎn)內(nèi)存比較緊張的話牍颈,內(nèi)存塊就可能被丟棄。這點(diǎn)類似于MRC&ARC晴圾,對(duì)象內(nèi)存回收機(jī)制颂砸。

- (void)discardContentIfPossible

當(dāng)counter等于0的時(shí)候,為了丟棄這些對(duì)象死姚,會(huì)調(diào)用這個(gè)方法人乓。

默認(rèn)情況下,NSDiscardableContent對(duì)象的counter變量初始值為1都毒,以確保對(duì)象不會(huì)被內(nèi)存管理系統(tǒng)立即釋放色罚。

- (BOOL)beginContentAccess    (counter++)

調(diào)用該方法,對(duì)象的counter會(huì)加1账劲;

與beginContentAccess相對(duì)應(yīng)的是endContentAccess戳护。如果可丟棄內(nèi)存不再被訪問時(shí)調(diào)用金抡。其聲明如下:

- (void)endContentAccess  (counter--)

該方法會(huì)減少對(duì)象的counter變量,通常是讓對(duì)象的counter值變回為0腌且,這樣在對(duì)象的內(nèi)容不再被需要時(shí)梗肝,就要以將其丟棄。

NSCache類提供了一個(gè)屬性铺董,來標(biāo)識(shí)緩存是否自動(dòng)舍棄那些內(nèi)存已經(jīng)被丟棄的對(duì)象(默認(rèn)該屬性為YES)巫击,其聲明如下:

@property BOOL evictsObjectsWithDiscardedContent

如果設(shè)置為YES,則在對(duì)象的內(nèi)存被丟棄時(shí)舍棄對(duì)象精续。

個(gè)人建議:如果需要使用緩存坝锰,直接用系統(tǒng)的NSCache就OK了,不要做死重付。

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];
    self.view.backgroundColor=[UIColor whiteColor];
    
    //添加緩存數(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é)果.png

**通過輸出結(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ù)了;

  1. 演示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é)果.png

通過結(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 之后确垫,無(wú)法再次往緩存池中添加數(shù)據(jù)
代碼演示:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    //當(dāng)收到內(nèi)存警告弓颈,調(diào)用removeAllObjects 之后,無(wú)法再次往緩存中添加數(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é)果為:


%u5728%u8FD9%u91CC%u8F93%u5165%u56FE%u7247%u6807%u9898

輸出結(jié)果

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市爬迟,隨后出現(xiàn)的幾起案子橘蜜,更是在濱河造成了極大的恐慌,老刑警劉巖付呕,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件计福,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡徽职,警方通過查閱死者的電腦和手機(jī)象颖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姆钉,“玉大人说订,你說我怎么就攤上這事〕逼浚” “怎么了陶冷?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)毯辅。 經(jīng)常有香客問我埂伦,道長(zhǎng),這世上最難降的妖魔是什么思恐? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任沾谜,我火速辦了婚禮膊毁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘基跑。我一直安慰自己婚温,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布媳否。 她就那樣靜靜地躺著缭召,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逆日。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天萄凤,我揣著相機(jī)與錄音室抽,去河邊找鬼。 笑死靡努,一個(gè)胖子當(dāng)著我的面吹牛坪圾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惑朦,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼兽泄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了漾月?” 一聲冷哼從身側(cè)響起病梢,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梁肿,沒想到半個(gè)月后蜓陌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吩蔑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年钮热,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烛芬。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡隧期,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赘娄,到底是詐尸還是另有隱情仆潮,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布擅憔,位于F島的核電站鸵闪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏暑诸。R本人自食惡果不足惜蚌讼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一辟灰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧篡石,春花似錦芥喇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至胖眷,卻和暖如春武通,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背珊搀。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工冶忱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人境析。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓囚枪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親劳淆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子链沼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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

  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。沛鸵。括勺。 其實(shí)如果沒有APIManager這一層是沒法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,192評(píng)論 1 23
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理曲掰,服務(wù)發(fā)現(xiàn)朝刊,斷路器,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 應(yīng)用場(chǎng)景: iOS中需要頻繁讀取的數(shù)據(jù)蜈缤,都可以用NSCache把數(shù)據(jù)緩存到內(nèi)存中提高讀取性能拾氓。 正文: 一:定義 ...
    謝謝生活閱讀 7,191評(píng)論 6 14
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司底哥,掛了不少咙鞍,但最終還是拿到小米、百度趾徽、阿里续滋、京東、新浪孵奶、CVTE疲酌、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,246評(píng)論 11 349
  • 1朗恳、獨(dú)立湿颅。一個(gè)人生活再難,也必須學(xué)會(huì)獨(dú)立粥诫,這樣就算所有人都離開你察郁,你還可以好好活下去早芭。 2谍珊、信任搀别。不要輕易試探你的...
    心情語(yǔ)錄閱讀 654評(píng)論 0 0