iOS 除SDWebImage之外清理記憶體中快取

weixin_33890499發表於2018-08-03
1444169-aa0dbb8248d9d48e.jpg
網路圖片

最近換了新的公司,已經兩個月沒有記錄過東西了,慚愧慚愧。剛好今天在做清理快取的功能,順便記錄一下:

通常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和清理時要格外注意,可根據自己的需要進行調整。


相關文章