iOS 除SDWebImage之外清理記憶體中快取
阿新 • • 發佈:2019-02-07
iOS 快取清理
最近換了新的公司,已經兩個月沒有記錄過東西了,慚愧慚愧。剛好今天在做清理快取的功能,順便記錄一下:
通常APP中清理快取主要分為兩大類:
1.通過SDWebImage載入的圖片檔案快取
2.通過NSFileManager計算快取資料夾內的快取並清理
SD的快取清理網上有很多,所以今天我這裡主要寫下第二種方式;
直接貼出程式碼解釋:
//清除快取按鈕的點選事件
//2018.08.02 注意這個路徑下東西輕易不要刪 所以不加入計算
//[self folderSizeAtPath:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject] +
CGFloat size = [self folderSizeAtPath:NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).lastObject] + [self folderSizeAtPath:NSTemporaryDirectory()];
NSString *message = size > 1 ? [NSString stringWithFormat:@"快取%.2fM, 確定刪除?", size] : [NSString stringWithFormat:@"快取%.2fK, 確定刪除?" , size * 1024.0];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"確定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction *action) {
//2018.08.02 注意清理的路徑 否則可能造成自動登入設定也失效
[self cleanCaches:NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).lastObject];
[self.view makeToast:@"清除快取成功!" duration:1.5 position:CSToastPositionCenter];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:nil];
[alert addAction:action];
[alert addAction:cancel];
dispatch_async(dispatch_get_main_queue(), ^{
[self showDetailViewController:alert sender:nil];
});
// 計算目錄大小
- (CGFloat)folderSizeAtPath:(NSString *)path{
// 利用NSFileManager實現對檔案的管理
NSFileManager *manager = [NSFileManager defaultManager];
CGFloat size = 0;
if ([manager fileExistsAtPath:path]) {
// 獲取該目錄下的檔案,計算其大小
NSArray *childrenFile = [manager subpathsAtPath:path];
for (NSString *fileName in childrenFile) {
NSString *absolutePath = [path stringByAppendingPathComponent:fileName];
size += [manager attributesOfItemAtPath:absolutePath error:nil].fileSize;
}
// 將大小轉化為M
return size / 1024.0 / 1024.0;
}
return 0;
}
// 根據路徑刪除檔案
- (void)cleanCaches:(NSString *)path{
// 利用NSFileManager實現對檔案的管理
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path]) {
// 獲取該路徑下面的檔名
NSArray *childrenFiles = [fileManager subpathsAtPath:path];
for (NSString *fileName in childrenFiles) {
// 拼接路徑
NSString *absolutePath = [path stringByAppendingPathComponent:fileName];
// 將檔案刪除
[fileManager removeItemAtPath:absolutePath error:nil];
}
}
}
這裡重點講下第一步計算size大小要注意的,可以看到這裡:
CGFloat size = [self folderSizeAtPath:NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).lastObject] + [self folderSizeAtPath:NSTemporaryDirectory()];
其實是傳遞兩個path路徑去計算相應資料夾下的內容的大小,上面註釋掉的部分其實只佔用了很小的空間,但是儲存的資訊確非常關鍵,比如我們平時經常用到的NSUserDefaults中的資料 如果計算的時候加上這個路徑。並且在呼叫清除方法
[self cleanCaches:"路徑"];
也寫入這個路徑的話 NSUserDefaults中儲存的資訊也會丟失,例如我們平常可能儲存的使用者自動登入的資訊扥扥,所以這裡在計算快取size和清理時要格外注意,可根據自己的需要進行調整。