APP是如何做到清除缓存的,下载的图片等文件
1> SDWebImage提供了一个方法专门计算下载的图片大小
//先获取图片文件大小
// [SDImageCache sharedImageCache].getSize;
2> 这里计算能计算包括文件和文件夹的大小
//给NSString写一个分类
用法
NSLog(@"文件地址".fileSize);
.h
- (unsigned long long)fileSize;
.m
- (unsigned long long)fileSize
{
// 总大小
unsigned long long size = 0;
// 文件管理者
NSFileManager *mgr = [NSFileManager defaultManager];
// 文件属性
NSDictionary *attrs = [mgr attributesOfItemAtPath:self error:nil];
if ([attrs.fileType isEqualToString:NSFileTypeDirectory]) { // 文件夹
// 获得文件夹的大小 == 获得文件夹中所有文件的总大小
NSDirectoryEnumerator *enumerator = [mgr enumeratorAtPath:self];
for (NSString *subpath in enumerator) {
// 全路径
NSString *fullSubpath = [self stringByAppendingPathComponent:subpath];
// 累加文件大小
size += [mgr attributesOfItemAtPath:fullSubpath error:nil].fileSize;
}
} else { // 文件
size = attrs.fileSize;
}
return size;
}
2.1> 和上面一样能计算文件和文件夹大小
- (unsigned long long)fileSize
{
// 总大小
unsigned long long size = 0;
// 文件管理者
NSFileManager *mgr = [NSFileManager defaultManager];
// 是否为文件夹
BOOL isDirectory = NO;
// 路径是否存在
BOOL exists = [mgr fileExistsAtPath:self isDirectory:&isDirectory];
if (!exists) return size;
if (isDirectory) { // 文件夹
// 获得文件夹的大小 == 获得文件夹中所有文件的总大小
NSDirectoryEnumerator *enumerator = [mgr enumeratorAtPath:self];
for (NSString *subpath in enumerator) {
// 全路径
NSString *fullSubpath = [self stringByAppendingPathComponent:subpath];
// 累加文件大小
size += [mgr attributesOfItemAtPath:fullSubpath error:nil].fileSize;
}
} else { // 文件
size = [mgr attributesOfItemAtPath:self error:nil].fileSize;
}
return size;
}
3>下面开始整清除
这里的Block里的self必须是weakSelf,保证在没有计算完成时候Pop回上一个界面cell自动消失(子线程里的计算结束)##
3.1 在这里我们选择在tableView的cell里实现这一效果,加载时候会计算自定义文件的大小,我们这里给了个死路径。
3.2 在计算过程中,VC不能Pop,以及cell不能点击清除命令,必须计算完毕才能点击清除,self.userInteractionEnabled = NO,所以计算时候会给NO
3.3 在代码中选择了给cell添加Tap的命令,而不是执行cell的代理方法,因为想在这个类里直接控制cell,如果执行代理方法,拿还得找cell
#define CustomCacheFile [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"Custom"]
@implementation ClearCacheCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
// 设置cell右边的指示器(用来说明正在处理一些事情)
UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[loadingView startAnimating];
self.accessoryView = loadingView;
// 设置cell默认的文字(如果设置文字之前userInteractionEnabled=NO, 那么文字会自动变成浅灰色)
self.textLabel.text = @"清除缓存(正在计算缓存大小...)";
// 禁止点击
self.userInteractionEnabled = NO;
__weak typeof(self) weakSelf = self;
// 在子线程计算缓存大小
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:2.0];
// 获得缓存文件夹路径
unsigned long long size = CustomCacheFile.fileSize;
size += [SDImageCache sharedImageCache].getSize;
// 如果cell已经销毁了, 就直接返回
if (weakSelf == nil) return;
NSString *sizeText = nil;
if (size >= pow(10, 9)) { // size >= 1GB
sizeText = [NSString stringWithFormat:@"%.2fGB", size / pow(10, 9)];
} else if (size >= pow(10, 6)) { // 1GB > size >= 1MB
sizeText = [NSString stringWithFormat:@"%.2fMB", size / pow(10, 6)];
} else if (size >= pow(10, 3)) { // 1MB > size >= 1KB
sizeText = [NSString stringWithFormat:@"%.2fKB", size / pow(10, 3)];
} else { // 1KB > size
sizeText = [NSString stringWithFormat:@"%zdB", size];
}
// 生成文字
NSString *text = [NSString stringWithFormat:@"清除缓存(%@)", sizeText];
// 回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
// 设置文字
weakSelf.textLabel.text = text;
// 清空右边的指示器
weakSelf.accessoryView = nil;
// 显示右边的箭头
weakSelf.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// 添加手势监听器
[weakSelf addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:weakSelf action:@selector(clearCache)]];
// 恢复点击事件
weakSelf.userInteractionEnabled = YES;
});
});
}
return self;
}
/**
* 清除缓存
*/
- (void)clearCache
{
// 弹出指示器
[SVProgressHUD showWithStatus:@"正在清除缓存..." maskType:SVProgressHUDMaskTypeBlack];
// 删除SDWebImage的缓存
[[SDImageCache sharedImageCache] clearDiskOnCompletion:^{
// 删除自定义的缓存
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSFileManager *mgr = [NSFileManager defaultManager];
[mgr removeItemAtPath:XMGCustomCacheFile error:nil];
[mgr createDirectoryAtPath:XMGCustomCacheFile withIntermediateDirectories:YES attributes:nil error:nil];
// 所有的缓存都清除完毕
dispatch_async(dispatch_get_main_queue(), ^{
// 隐藏指示器
[SVProgressHUD dismiss];
// 设置文字
weakSelf.textLabel.text = @"清除缓存(0B)";
});
});
}];
}
/**
* 在这里还要这个,引文计算需要时间,计算时下滑,在上滑菊花酒会消失
当cell重新显示到屏幕上时, 也会调用一次layoutSubviews
*/
- (void)layoutSubviews
{
[super layoutSubviews];
// cell重新显示的时候, 继续转圈圈
UIActivityIndicatorView *loadingView = (UIActivityIndicatorView *)self.accessoryView;
[loadingView startAnimating];
}