什麼是NSCache緩存
NSCache主要用來存儲臨時數據(鍵值對),當內存資源不夠時,系統會自動釋放部分數據。它有三個特色:
• NSCache爲了保持不佔用過多的系統內存,它有多種自動回收內存策略;當系統內存出現不足時,它會回收部份內存使系統正常運轉,這種回收是不可控的。
• 能夠在多線程中對NSCache進行訪問,同時不須要加鎖,由於它是線程安全的。
• 與NSMutableDictionary不一樣,NSCache不會copy其內部的鍵對象。
由上邊的特色看出,NSCache是一個很好的內存緩存類,經過它咱們能夠實現數據的緩存功能。常見的開源框架中也有NSCache的使用,AFN的圖片緩存,SDWebImage等。安全
NSCache測試多線程
下面驗證NSCache的特性,包含三個部分。NSCache的緩存能力有多大?多線程訪問下是否安全?是否會copy其內部對象?框架
1. 緩存能力
NSCache提供了totalCostLimit和countLimit屬性讓外界可以對其進行緩存大小和緩存數量進行限制,可是不精確。網上其餘的帖子說到大約NSCache的緩存能力是500M,如今咱們對其驗證。
NSCache *cache = [[NSCache alloc] init];
int a = 0;
while (YES) {
NSString *string = @"一長串字符串"; // 大約1000個左右字符
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSString *key = [NSString stringWithFormat:@"%d", a];
[cache setObject:data forKey:key];
a++;
}
經過上述的代碼運行在iPhone6上,內存升到600M多點直接崩潰,那麼極限是500多應該是正確的。同時在快速達到內存極限時,系統是來不及釋放回收的,使用時應當注意,並且上邊的代碼是死循環,速度很是快。
2. 多線程訪問
多線程訪問單獨讀取是不會形成問題的,除非訪問線程數過多,這裏咱們模擬多線程同時寫入的狀況。
NSCache *cache = [[NSCache alloc] init];
NSString *string = @"一長串字符串"; // 大約1000個左右字符
for (int i = 0; i < 10; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[cache setObject:[NSString stringWithFormat:@"%d%@",i,string] forKey:@"MulPth"];
NSLog(@"object is %@", [cache objectForKey:@"MulPth"]);
});
}async
string若設置爲特別短的字符串,效果可能不是很明顯,因此將緩存能力中的字符串拷貝過來測試,從打印結果看,時間戳有明顯差別,同時順序也不是0123456789,而其他的內容一致,能夠得出是線程安全的。
本質上,NSCache在其內部使用了pthread_mutex互斥鎖進行線程安全保護。測試