iOS緩存策略——NSCache的簡單使用

iOS 蘋果公司 技術 CocoaChina CocoaChina 2017-09-03

今天來共同學習一下NSCache的相關知識,有疏忽的地方,還望各位不吝賜教。

一、簡介

1、NSCache是蘋果官方提供的的緩存類,具體使用是和NSDictionary很相似的,在AFNetworking和SDWebImage第三方框架中被用作管理緩存。

2、NSCache在系統內存很低時會自動釋放對象,但是在模擬器進行演示的時候不會釋放,這一點要注意,所以最好是在內存進行警告時主動去調用方法去釋放對象。

3、NSCache是線程安全的,在進行多線程操作時,不需要進行加鎖。

4、NSCache的Key只是對對象進行了Strong引用,而非拷貝,相關說明會在下面的例子中進行詳細解釋。

二、屬性和方法說明

1、屬性說明

// 緩存空間的最大成本,超出上限會自動回收對象,默認值是0,表示沒有限制。

@property NSUInteger totalCostLimit;

// 能夠緩存對象的最大數量。默認值為0,表示沒有限制。

@property NSUInteger countLimit;

// 標識緩存是否回收廢棄的內容。

@property BOOL evictsObjectsWithDiscardedContent;

2、方法說明

// 通過指定的鍵取出在緩存中存儲的數據。

- (nullable ObjectType)objectForKey:(KeyType)key;

// 在緩存中設置指定鍵名對應的值,成本為0。

- (void)setObject:(ObjectType)obj forKey:(KeyType)key;

// 在緩存中設置指定鍵名對應的值,並且指定回收成本,以便進行計算存儲在緩存中對象的總成本,當出現內存警告或者超出總成本時,緩存就會進行刪除部分元素的操作。

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

// 通過指定的鍵清除在緩存中存儲的數據。

- (void)removeObjectForKey:(KeyType)key;

// 清除在緩存中存儲的所有數據。

- (void)removeAllObjects;

三、簡單使用

/**

* 在此提供一個例子來進行緩存使用的說明

* 需求:將字符串存入緩存,並進行查看和清理。

* 準備:在Main.storyboard中添加按鈕,分別為添加、檢查和刪除緩存。(在此使用需要成本的方式進行測試)

*/

1、創建緩存對象

1
2
3
4
5
6
7
8
9
10
11
12
13
/** 緩存屬性 */
@property (nonatomic, strong) NSCache *cache;
// 通過懶加載的方式創建緩存對象
- (NSCache *)cache{
if (!_cache) {
_cache = [[NSCache alloc] init];
// 設置成本為5 當存儲的數據超過總成本數,NSCache會自動回收對象
_cache.totalCostLimit = 5;
// 設置代理 代理方法一般不會用到,一般是進行測試的時候使用
_cache.delegate = self;
}
return _cache;
}

2、實現按鈕的點擊方法

1
2
3
4
5
6
7
8
9
// 添加緩存
- (IBAction)addCache {
for (int i = 0 ; i < 10 ; i++) {
NSString *str = [NSString stringWithFormat:@"在這裡進行了存儲數據"];
// 設置成本數為1
[self.cache setObject:str forKey:@(i) cost:1];
NSLog(@"存儲數據----%@",@(i));
}
}
1
2
3
4
5
6
7
8
9
10
// 檢查緩存
- (IBAction)checkCache {
NSLog(@"---------------------------------------------");
for (int i = 0; i < 10 ; i++) {
NSString *str = [self.cache objectForKey:@(i)];
if (str) {
NSLog(@"取出緩存中存儲的數據-----%@",@(i));
}
}
}
1
2
3
4
5
// 清理緩存
- (IBAction)deleteCache {
[self.cache removeAllObjects];
NSLog(@"清理緩存");
}

3、實現代理

1
2
3
4
5
#pragma mark - NSCacheDelegate
// 即將回收對象的時候進行調用,實現代理方法之前要遵守NSCacheDelegate協議。
- (void)cache:(NSCache *)cache willEvictObject:(id)obj{
NSLog(@"回收--------%@",obj);
}

4、打印說明

4.1 點擊添加按鈕的打印

存儲數據----0

存儲數據----1

存儲數據----2

存儲數據----3

存儲數據----4

回收--------在這裡進行了存儲數據

存儲數據----5

回收--------在這裡進行了存儲數據

存儲數據----6

回收--------在這裡進行了存儲數據

存儲數據----7

回收--------在這裡進行了存儲數據

存儲數據----8

回收--------在這裡進行了存儲數據

存儲數據----9

4.2 點擊檢查按鈕的打印

---------------------------------------------

取出緩存中存儲的數據-----5

取出緩存中存儲的數據-----6

取出緩存中存儲的數據-----7

取出緩存中存儲的數據-----8

取出緩存中存儲的數據-----9

4.3 打印相關的解釋

在此因為進行每個字符串對象存儲時,成本是1,我們設置的總成本是5,字符串對象存儲了10次,總成本是10,所以在存儲數據5的時候會回收數據1的字符串對象,以此類推,所以打印的結果如上所示。關於清理緩存和其他相關的操作由讀者們自行打印,在此不做贅述了。

四、簡介中遺漏的話

/**

* 如果把例子中的添加緩存寫成如下方式,就不會存在回收的打印,在檢查緩存的時候也會有10條數據。

* 解釋:NSCache的Key只是對對象進行了Strong引用,而非拷貝。

* 當寫在for循環外部時,所以對於字符串對象只是在內存中建立了10個強引用,而存儲的真正的字符串對象只有一個(字符串對象只創建了一次),所以總成本為1。

* 當寫在for循環外部時,字符串對象只是在內存中建立了10個強引用,而存儲的真正的字符串對象只有十個(每次都在創建新的字符串對象),所以總成本為10。

*/

1
2
3
4
5
6
7
8
9
10
// 添加緩存
- (IBAction)addCache {
// NSCache的Key只是對對象進行了Strong引用,而非拷貝,
NSString *str = [NSString stringWithFormat:@"在這裡進行了存儲數據"];
for (int i = 0 ; i < 10 ; i++) {
// 設置成本數為1
[self.cache setObject:str forKey:@(i) cost:1];
NSLog(@"存儲數據----%@",@(i));
}
}

寫在最後的話:NSCache的簡單使用介紹就到這裡,關於iOS緩存策略方面的問題歡迎大家和我交流,共同進步,謝謝各位。

iOS緩存策略——NSCache的簡單使用

相關推薦

推薦中...