缓存相关

1.使用第三方框架sdWebImage 下载的图片,要计算出他的大小,使用

#import 
NSUInteger cacheSize = [[SDImageCache sharedImageCache]getSize];

获取文件夹缓存原理:
1.获取文件夹路径
2.遍历子文件,拼接全文件名
3.通过文件管理类获取文件信息 dict.fileSize

-(unsigned long long)getFileSize:(NSString *)directoryPath
{
    //1.获取缓存文件夹
    NSString * cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
    //2.拼接文件夹路径
    NSString * filePath = [cachePath stringByAppendingPathComponent:directoryPath];
    //3.判断是否文件夹 是 遍历子文件夹,算出文件总大小; 否 算出当前文件夹
    NSFileManager * mgr = [NSFileManager defaultManager];
    unsigned long long cacheSize = 0;
    BOOL isDirectory = NO;
    BOOL isExist=  [mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if ( ! isExist)
    {
        NSException * exception = [NSException exceptionWithName:@"非法路径" reason:@"路径不存在" userInfo:nil];
        [exception raise];
    }
    if (isDirectory) {
        NSDirectoryEnumerator * enumerator = [mgr enumeratorAtPath:filePath];
        for (NSString * subPath in enumerator) {
            NSString * fullPath = [filePath stringByAppendingPathComponent:subPath];
            NSDictionary * dict = [mgr attributesOfItemAtPath:fullPath error:nil];
            cacheSize += dict.fileSize;
        }
    }
    else {
        cacheSize = [mgr attributesOfItemAtPath:filePath error:nil].fileSize;
    }
    return cacheSize;
}

处理不同cell共存,将清除缓存的cell抽成自定义cell

static NSString * const LMClearCellID = @"LMClearCellID";
@implementation LMSettingController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView registerClass:[LMClearCell class]forCellReuseIdentifier:LMClearCellID];
    
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    return [tableView dequeueReusableCellWithIdentifier:LMClearCellID];
}

换算单位

-(NSString *) cacheStr
{
    if (_cacheStr == nil) {
        
        if (_cacheSize > pow(10, 9)) {
            
            _cacheStr = [NSString stringWithFormat:@"清除缓存(%.2fGB)",_cacheSize / pow(10, 9)];
        }
        else if (_cacheSize > pow(10, 6)){
            _cacheStr = [NSString stringWithFormat:@"清除缓存(%.2fMB)",_cacheSize / pow(10, 6)];
        }
        else if (_cacheSize > pow(10, 3)){
            _cacheStr = [NSString stringWithFormat:@"清除缓存(%.2fKB)",_cacheSize / pow(10, 3)];
        }
        else
        {
            _cacheStr = [NSString stringWithFormat:@"清除缓存(%zdB)",_cacheSize];
        }
    }
    return _cacheStr;
}

开启子线程计算大小

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.textLabel.text = @"正在计算大小...";
        self.userInteractionEnabled = NO;
          __weak typeof (self)  weakSelf = self;
        
        //开启子线程计算大小
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(5);
             NSString * cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
            NSString * filePath = [cachePath stringByAppendingPathComponent:@"default"];
            weakSelf.cacheSize = [LMFileCacheManger getFileSize:filePath];
            if (weakSelf == nil) return ;
          dispatch_async(dispatch_get_main_queue(), ^{
              weakSelf.textLabel.text = weakSelf.cacheStr;
              weakSelf.userInteractionEnabled = YES;
          });
            
        });
    }
    return  self;
}

点击cell删除缓存
1.先删除SDWebImage的缓存,再删除自己的缓存
2.根据需要重新创建自己的文件夹

(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell isKindOfClass:[LMClearCell class]]) {
        LMClearCell * clearCell = (LMClearCell *)cell;
        [clearCell clearCache];
    }
}
---
-(void)clearCache
{
    //先删除SDWebImage的缓存
    [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{
        NSString * path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
        NSLog(@"%@",path);
        NSString* fullpath = [path stringByAppendingPathComponent:@"custom"];
        
        [LMFileCacheManger clearFileCache:fullpath]; //删除自己的文件夹
        dispatch_async(dispatch_get_main_queue(),^{//回到主线程刷新UI
            self.textLabel.text = @"清除缓存(0B)";
        });
        
    }];
    
}

---
+(void)clearFileCache:(NSString *)filePath
{
    [SVProgressHUD showWithStatus:@"正在删除"];

    [SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeBlack];
    
    NSFileManager * mgr = [NSFileManager defaultManager];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [mgr removeItemAtPath:filePath error:nil];
        
       dispatch_async(dispatch_get_main_queue(), ^{
           [SVProgressHUD showSuccessWithStatus:@"删除成功"];
       });
    });
    
}

用户体验细节
1.如果缓存文件非常大,那么应该开启子线程下载
2.当前正在计算过程中,cell不能被点击
3.当用户在计算缓存过程中,点击返回按钮,退出当前控制器,那么无需再回到主线程刷新UI

 // 如果cell已经销毁了, 就直接返回
            if (weakSelf == nil) return;

遇到的bug
1.设置cell默认的文字(如果设置文字之前userInteractionEnabled=NO, 那么文字会自动变成浅灰色)

  self.textLabel.text = @"清除缓存(正在计算缓存大小...)";
  self.userInteractionEnabled = NO;

2.block 强引用(block会对外部对象进行强引用,直到block执行完才会销毁)

 __weak typeof(self) weakSelf = self; //__weak修饰

相关博客:
http://www.jianshu.com/p/76614766b2ea
http://www.cnblogs.com/pengyingh/articles/2350345.html

你可能感兴趣的:(缓存相关)