APP清除緩存功能的具體實現

sufangqi 8年前發布 | 15K 次閱讀 iOS開發 C語言 移動開發

幾乎每一個 App 都有清除緩存的功能, 不然沙盒中的文件太多, 是很占用用戶的資源的, 一個簡單的清除緩存的功能我們可以單獨用一個類來實現.

清除緩存的功能說白了就是講沙盒中的 Cache 文件夾中的所有子文件和子文件夾全部刪除, 在項目當中, 還需要向用戶展示緩存的大小, 這就涉及到要計算文件的大小.

所以, 我們的任務就是, 計算沙盒中 Cache 文件的大小, 并將其子文件和子文件夾刪除

  • 首先我們建一個工具類

清除緩存工具類

  • 我們在工具類中建一個單例方法

+ (instancetype)yf_sharedManager {
    static YFWipeCacheManager *manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[YFWipeCacheManager alloc] init];
    });
    return manager;
}
  • 暴露一個對象方法, 根據路徑計算文件大小

    其實我們這個類的目的除了清除緩存之外, 還有一個功能就是可以計算任何路徑下的文件及文件夾的大小

#pragma mark - 計算單個文件的大小
- (CGFloat)yf_fileSizeAtPath:(NSString *)path {
     /* 如果這個路徑文件存在的話, 就計算出文件的大小并返回, 否則就返回0 */
    if ([kFileManager fileExistsAtPath:path]) {
        unsigned long long size = [kFileManager attributesOfItemAtPath:path error:NULL].fileSize;
        return size / 1024.0 / 1024.0;
    }
    return 0;
}
  • 計算緩存文件夾中的文件大小

    因為蘋果沒有提供 API 直接計算文件夾的大小, 那么我們就需要遍歷整個文件夾,來計算文件夾下單個文件的大小

#pragma mark - 計算緩存文件夾的大小
 /* 因為蘋果沒有提供 API 直接計算文件夾的大小, 那么我們就需要遍歷整個文件夾,來計算文件夾下單個文件的大小 */
- (CGFloat)yf_cacheSize {
    /* 先將屬性 cacheSize 的大小置為0,這樣每次計算的文件夾大小的時候就不會重復累加 */
    self.cacheSize = 0;
    NSDirectoryEnumerator *enumerator = [kFileManager enumeratorAtPath:kCachePath];
    __weak typeof(self)weakSelf = self;
     /* 遍歷 cache 文件夾路徑中的子路徑,然后計算每單個文件的大小,累加后返回 */
    [enumerator.allObjects enumerateObjectsUsingBlock:^(NSString *subPath, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *path = [kCachePath stringByAppendingPathComponent:subPath];
        weakSelf.cacheSize += [self yf_fileSizeAtPath:path];
    }];
    return self.cacheSize;
}
  • 計算其他文件夾的大小

    方法同計算 cache 文件夾大小一樣

#pragma mark - 計算其他文件夾的大小 
 /* 方法同計算 cache 文件夾大小 */
- (CGFloat)yf_folderSizeAtPath:(NSString *)path {
    CGFloat folderSize = 0;
    __block CGFloat blockFolderSize = folderSize;
    if ([kFileManager fileExistsAtPath:path]) {
        NSDirectoryEnumerator *enumerator = [kFileManager enumeratorAtPath:path];
        [enumerator.allObjects enumerateObjectsUsingBlock:^(NSString *subPath, NSUInteger idx, BOOL * _Nonnull stop) {
            NSString *absolutePath = [path stringByAppendingPathComponent:subPath];
            blockFolderSize += [self yf_fileSizeAtPath:absolutePath];
        }];
        return folderSize;
    }
    return 0;
}
  • 我們除了要計算緩存文件的大小, 最重要的是要刪除這些緩存文件

    清除緩存文件是一個耗時操作, 我們需要開啟一個異步操作, 即開啟子線程

#pragma mark - 清除緩存文件
- (void)yf_wipeCacheAction {
     /* 清除緩存文件是一個耗時操作, 我們需要開啟一個異步操作 */
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         /* 在這個 block 中, 方法跟計算 cache 文件夾的大小一樣, 只不過最后是清除文件 */
        NSDirectoryEnumerator *enumerator = [kFileManager enumeratorAtPath:kCachePath];
        [enumerator.allObjects enumerateObjectsUsingBlock:^(NSString *subPath, NSUInteger idx, BOOL * _Nonnull stop) {
            /* 錯誤處理 */
            NSError *error = nil;
            NSString *path = [kCachePath stringByAppendingPathComponent:subPath];
            if ([kFileManager fileExistsAtPath:path]) {
                [kFileManager removeItemAtPath:path error:&error];
                if (error) {
                    NSLog(@"文件刪除失敗");
                }else {
                    NSLog(@"文件刪除成功");
                }
            }
        }];
    });
}
  • 在實際的項目中, 我們可以暴露一個類方法, 實現一鍵式地清除緩存

    包含以下幾個步驟

    1.彈出蒙版, 計算緩存文件夾的大小

    2.彈出提示框, 提示用戶是否要清除緩存

    3.當用戶點擊取消按鈕時,不做任何操作

    4.當用戶點擊確定按鈕時,清除緩存,并提示用戶緩存清除成功

#pragma mark - 最后暴露一個類方法, 只要調用這個,自動彈出清除緩存提示框, 需要同 MBProgressHud 配合使用

+ (void)yf_wipeCacheWithDefaultStyle {
    MBProgressHUD *hud = [MBProgressHUD showHudTo:kTopStackController.view image:nil text:@"正在計算緩存大小" animated:YES];
     /* 由于計算緩存大小也是一個耗時操作. 我們做一個延時. 來確保獲取到數據 */
    __weak typeof(self)weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        UIAlertController *alterVC = [UIAlertController alertControllerWithTitle:@"清除緩存" message:[NSString stringWithFormat:@"APP當前的緩存為:%.2fM",[[weakSelf yf_sharedManager] yf_cacheSize]] preferredStyle:UIAlertControllerStyleActionSheet];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            [kTopStackController dismissViewControllerAnimated:YES completion:nil];
        }];
        UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
            [[weakSelf yf_sharedManager] yf_wipeCacheAction];
            MBProgressHUD *clearHud = [MBProgressHUD showHudTo:kTopStackController.view image:nil text:@"清除成功" animated: YES];
            clearHud.mode = MBProgressHUDModeText;
            [clearHud hide:YES afterDelay:2.0];
        }];
        [alterVC addAction:cancelAction];
        [alterVC addAction:confirmAction];
        [kTopStackController presentViewController:alterVC animated:YES completion:nil];
    });
    [hud hide:YES afterDelay:1.0];
}

所以這個類最基礎的使用方法就是在按鈕的點擊事件中加入這樣一句代碼

[YFWipeCacheManager yf_wipeCacheWithDefaultStyle];

不過有一點不方便的是, 必須要和 MBProgressHUD 這個第三方框架聯合使用, 如果大家不想這么做的話, 也無需理會, 用這個類中的其他方法配合自定義, 也能夠實現類似的效果.

下面就是實現的效果圖:

清除緩存實現效果圖

 

 

來自:http://www.jianshu.com/p/b2619155504f

 

 本文由用戶 sufangqi 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!