前言
移动应用在处理网络资源时,一般都会做离线缓存处理,其中以图片缓存最为典型,其中很流行的离线缓存框架为sdwebimage
。但是,离线缓存会占用手机存储空间,所以缓存清理功能基本成为资讯、购物、阅读类app的标配功能。
清除缓存基本上都是在设置界面的某一个cell,于是我们可以把清除缓存封装在某一个自定义cell中
如下图所示:
实现的具体步骤
使用注意:过程中需要用到第三方库,请提前安装好:sdwebimage
、svprogresshud
。
1. 创建自定义cell,命名为gylclearcachecell
重写initwithstyle:(uitableviewcellstyle)style reuseidentifier:(nsstring *)reuseidentifier
方法,设置基本内容,如文字等等;
主要代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
- (instancetype)initwithstyle:(uitableviewcellstyle)style reuseidentifier:(nsstring *)reuseidentifier
{
if (self = [super initwithstyle:style reuseidentifier:reuseidentifier]) {
// 设置加载视图
uiactivityindicatorview *loadingview = [[uiactivityindicatorview alloc] initwithactivityindicatorstyle:uiactivityindicatorviewstylegray];
[loadingview startanimating];
self.accessoryview = loadingview;
//设置文字
self.textlabel.text = @ "清楚缓存" ;
self.detailtextlabel.text = @ "正在计算" ;
}
return self;
}
|
2. 计算缓存文件大小
缓存文件包括两部分,一部分是使用sdwebimage
缓存的内容,其次可能存在自定义的文件夹中的内容(视频,音频等内容),于是计算要分两部分
主要代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
unsigned long long size =
[nssearchpathfordirectoriesindomains(nscachesdirectory, nsuserdomainmask, yes).lastobject stringbyappendingpathcomponent:@ "customfile" ].filesize;
//filesize是封装在category中的。
size += [sdimagecache sharedimagecache].getsize; //customfile + sdwebimage 缓存
//设置文件大小格式
nsstring sizetext = nil;
if (size >= pow (10, 9)) {
sizetext = [nsstring stringwithformat:@ "%.2fgb" , size / pow (10, 9)];
} else if (size >= pow (10, 6)) {
sizetext = [nsstring stringwithformat:@ "%.2fmb" , size / pow (10, 6)];
} else if (size >= pow (10, 3)) {
sizetext = [nsstring stringwithformat:@ "%.2fkb" , size / pow (10, 3)];
} else {
sizetext = [nsstring stringwithformat:@ "%zdb" , size];
}
|
上述两个方法都是在主线程中完成的,如果缓存文件大小非常大的话,计算时间会比较长,会导致应用卡死,考虑到该问题,因此需要将上述代码放到子线程中完成。
3. 添加手势监听
对于监听点击cell可以使用代理也可以使用手势监听,为了将完整的功能封装到自定义cell中,于是我们使用手势监听的方法来监听点击cell。
1
2
3
4
5
6
7
8
9
|
//计算完成后,回到主线程继续处理,显示文件大小,除去加载视图,显示箭头,添加点击事件
dispatch_async(dispatch_get_main_queue(), ^{
self.detailtextlabel.text = [nsstring stringwithformat:@ "%@" ,sizetext];
self.accessoryview = nil;
self.accessorytype = uitableviewcellaccessorydisclosureindicator;
[self addgesturerecognizer:[[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(clearcacheclick)]];
});
|
4. 清除缓存
清除缓存也是分为两部分,一是清除sdwebimage
的缓存,二是清除自定义文件缓存
主要代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
- ( void )clearcacheclick
{
[svprogresshud showwithstatus:@ "正在清除缓存···" ];
[svprogresshud setdefaultmasktype:svprogresshudmasktypeblack];
[[sdimagecache sharedimagecache] cleardiskoncompletion:^{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
nsfilemanager *mgr = [nsfilemanager defaultmanager];
[mgr removeitematpath:gylcustomfile error:nil];
[mgr createdirectoryatpath:gylcustomfile withintermediatedirectories:yes attributes:nil error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[svprogresshud dismiss];
// 设置文字
self.detailtextlabel.text = nil;
});
});
}];
}
|
注意点:sdwebimage
清除缓存是在子线程中进行的,清除自定义文件内容应该也放在子线程中(删除大文件可能比较耗时),为了保证两者不冲突,可以将删除自定义文件内容放在sdwebimage
缓存清除完毕之后进行,然后再回到主线程操作。
5. 其他注意点
a. 在计算文件大小过程中应该是不允许点击cell的,如果有设置cell的didselectrowatindexpath
方法,那么会导致手势监听不能使用。于是需要在计算时不能点击cell。
b. 设置userinteractionenabled=no
应放在设置文字之后,否则textlabel
将显示为灰色。
c. 当计算文件大小没有结束的时,这个时候点击返回,自定义cell不会被销毁,他会执行完剩下的代码,可以使用dealloc
方法来验证,在此情况下,可以使用弱引用的self
来解决。
d. 当设置界面的cell比较多时,如果还在计算缓存大小时,清除缓存的cell从视图中消失,那么加载视图动画就会被停止,当返回到清除缓存cell时,看不到加载动画。解决方案两种方法:一个是在cell创建的代理方法中重新开启动画;另一个是封装到layoutsubviews方法中。
6. 效果
总结
以上就是关于ios中清除缓存功能实现的全部内容,希望这篇文章对各位ios开发者们能有所帮助,如果有疑问大家可以留言交流。