前言:最近在做一個練手小項目统翩,由于項目中用到了如SDWebImage這類有緩存處理的框架娇豫,程序運行過程中會產(chǎn)生一些緩存锣杂,而我們知道很多app內(nèi)都有獲取緩存大小和清除緩存功能脂倦,于是我也動手做了一下。
緩存存在原因:
在程序運行過程中元莫,我們可能需要多次請求同一個鏈接來獲取數(shù)據(jù)赖阻,比如微博,微信朋友圈功能踱蠢,但如果每次都發(fā)送一條新的請求來獲取數(shù)據(jù)話會造成以下問題:
(1) 用戶流量的浪費
(2) 程序響應(yīng)速度不夠快,用戶體驗差
為了解決上面的問題火欧,一般考慮對數(shù)據(jù)進行緩存.App需要緩存的主要原因就是改善應(yīng)用所表現(xiàn)出的性能。將應(yīng)用內(nèi)容緩存起來可以支持離線茎截、節(jié)省用戶流量苇侵、減少加載時間等。緩存機制一般有兩種企锌。第一種是“按需緩存”榆浓,這種情況下應(yīng)用緩存起請求應(yīng)答,就和Web瀏覽器的工作原理一樣撕攒;第二種是“預(yù)緩存”陡鹃,這種情況是緩存全部內(nèi)容(或者最近n條記錄)以便離線訪問。
如何獲取一個應(yīng)用下的緩存數(shù)據(jù)以及計算緩存大写蛉础:
我們知道一個app下會有個cache文件夾杉适,專門來保存緩存文件,我們想要獲取文件緩存柳击,只需要獲取cache文件夾路徑猿推,然后遍歷文件夾路徑下的所有文件(不包括文件本身,因為文件夾也是有大小的捌肴,獲取文件夾本身的話會使獲取的緩存大于真實緩存)并計算文件大小蹬叭,即可算得緩存大小。這部分在很多框架中都會用到,比如SDWebImage中獲取文件夾大小內(nèi)容的代碼實現(xiàn)如下:
#pragma mark - Cache Info
- (NSUInteger)getSize {
__block NSUInteger size = 0;
dispatch_sync(self.ioQueue, ^{
// 枚舉路徑下的所有子文件
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
for (NSString *fileName in fileEnumerator) {
NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
// 使用文件管理者獲取文件屬性
NSDictionary<NSString *, id> *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
size += [attrs fileSize];
}
});
return size;
}
因此我們參考這個代碼状知,將目標目錄替換成cache文件夾,由于緩存可能很大秽五,讀取文件是個耗時操作,所以我們開啟子線程處理獲取緩存大小操作饥悴,當執(zhí)行完成坦喘,用block將結(jié)果返回出去,代碼實現(xiàn)如下:
+ (void)getFileSize:(NSString *)cachePath completion:(void (^)(NSInteger))completion {
// 1.創(chuàng)建文件管理者對象
NSFileManager *mgr = [NSFileManager defaultManager];
// 異常處理
BOOL isDirectory;
[mgr fileExistsAtPath:cachePath isDirectory:&isDirectory];
if (!isDirectory) {
NSException *exp = [NSException exceptionWithName:@"invalid cache directory" reason:@"笨蛋盲再,要傳入一個文件路徑" userInfo:nil];
[exp raise];
}
// 2.獲取緩存目錄下的所有文件
NSArray *pathArr = [mgr subpathsAtPath:cachePath];
// 開啟子線程處理耗時操作
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSInteger totalSize = 0;// 統(tǒng)計文件總大小
// 3.遍歷文件目錄下的所有文件
for (NSString *path in pathArr) {
// 4.拼接文件真實路徑
NSString *filePath = [cachePath stringByAppendingPathComponent:path];
// 5.判斷是否為文件夾
BOOL isExist;
BOOL isDirectory;
isExist = [mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (!isExist || isDirectory) continue;
// 6.獲取文件大小
NSDictionary *attrs = [mgr attributesOfItemAtPath:filePath error:nil];
totalSize += [attrs fileSize];
// 將獲取到的文件傳遞出去
dispatch_sync(dispatch_get_main_queue(), ^{
if (completion) {
completion(totalSize);
}
});
}
});
}
如何清除緩存
與獲取緩存的思路相同,遍歷所有文件瓣铣,然后刪除文件答朋,代碼簡單易懂。話不多說棠笑,直接上代碼:
+ (void)removeDirectory:(NSString *)filePath {
// 1.創(chuàng)建文件管理者對象
NSFileManager *mgr = [NSFileManager defaultManager];
// 異常處理
BOOL isDirectory;
BOOL isExist;
isExist = [mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (!isDirectory || !isExist) {
NSException *exp = [NSException exceptionWithName:@"invalid cache directory" reason:@"笨蛋梦碗,要傳入一個文件路徑,并且文件路徑要存在!" userInfo:nil];
[exp raise];
}
// 2.獲取緩存目錄下的所有文件夾
NSArray *pathArr = [mgr contentsOfDirectoryAtPath:filePath error:nil];
// 3.遍歷文件目錄下的所有文件
for (NSString *path in pathArr) {
// 4.拼接文件真實路徑
NSString *realPath = [filePath stringByAppendingPathComponent:path];
// 5.刪除文件
[mgr removeItemAtPath:realPath error:nil];
}
}
PS:最后如果各位大佬發(fā)現(xiàn)那里有問題歡迎批評指出蓖救,覺得有用點個喜歡~