23 手机上内存清理

设置界面中清除缓存的处理 (抄录转载)

应用中清除缓存的处理

www.jianshu.com/p/1ee0761624a6

1

手机上的磁盘缓存 == 从网络上下载的数据 + 写入的数据

手机上的磁盘缓存的数据类型 == 图片 + 多媒体文件(音频/视频)

它们存在于沙盒中

这里要清除缓存,就要拿到沙盒中存在的缓存的大小,就是看我们下载的图片文件有多大,然后把它显示在cell当中

因为我们下载图片用到是SDWebImage框架,所以我们要获取所下载图片的缓存大小,最简单的方法也是使用SDWebImage里面的东西--SDImageCache

23 手机上内存清理_第1张图片

2

获取磁盘缓存的大小,它是一个单例,在mac和ios中,数据的大小不是以1024为单位的而是以1000为单位,不用弄混淆了

获取沙盒路径:

NSLog(@"%@",NSTemporaryDirectory());

单位是Mb

NSLog(@"%f",[SDWebImageCache sharedImageCache].getSize);


3沙盒结构

Documents 不允许存放大型文件,备份ITunes,缓存文件放这里边,是不允许通过的

Library:存放缓存文件(整个缓存在default文件夹)和用户偏好设置

temp:临时变量

23 手机上内存清理_第2张图片


4获取文件和文件夹大小

SDWebImage只用了一个类FileManager

只能获取文件的大小,不能获取整个文件夹 大小


//文件管理者

NSFileManager *mgr = [NSFileManager defaultManager];

//查找default文件夹,拿到路径

//先拿到Cache文件夹路径,返回的是个数组,取第一个

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

NSString *file = [caches stringByAppendingPathComponent:@"default"];// 拼接的路径

//    NSString *file = [caches stringByAppendingString:@"default"];// 这是拼接的字符串


获取文件属性

// 它只给你文件夹这个壳子有多大,没有给里面的文件有多大

NSDictionary *attrs = [mgr attributesOfItemAtPath:file error:nil];

在Mac中不能直接拿到文件夹的大小,只能对文件夹进行一层一层的遍历,去拿到里面文件的大小,然后全部加起来

所以我们得遍历文件夹里面所以的文件,然后把里面所有文件的FileSize加起来


方法一:

// 总大小

NSInteger size = 0;

// 文件路径

// 先拿到caches文件夹路径(它返回的是数组,所以取第一个)

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

NSString *file = [caches stringByAppendingPathComponent:@"default"];// 拼接的路径

//    NSString *file = [caches stringByAppendingString:@"default"];// 这是拼接的字符串

// 文件管理者

NSFileManager *mgr = [NSFileManager defaultManager];

// 获得文件夹中的所有内容

//        NSArray *contents = [mgr contentsOfDirectoryAtPath:file error:nil];

//        它只能获得它当前文件夹的内容,不能往里面深挖,这里不用它

//        subpaths 获取文件夹里面文件的子路径,什么文件都能拿到了(文件夹能拿到,文件夹里面的文件也能拿到)

//        所以用subpaths就是做好的,只要给我们一个最根的文件夹,我们就能找到里面所有的文件,不需要一遍一遍递归去找了

NSArray *subpaths = [mgr subpathsAtPath:file];

for (NSString *subpath in subpaths) {

// 获得全路径

NSString *fullSubpath = [file stringByAppendingPathComponent:subpath];

// 获得文件属性

NSDictionary *attrs = [mgr attributesOfItemAtPath:fullSubpath error:nil];

//        size += [attrs[NSFileSize] integerValue];

size += attrs.fileSize;

}

这个方式是通过拼接所有的路径而去获取缓存的大小


方法二:

// 总大小

NSInteger size = 0;

// 文件路径

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

NSString *file = [caches stringByAppendingPathComponent:@"default"];

// 文件管理者

NSFileManager *mgr = [NSFileManager defaultManager];

// 获得文件夹中的所有内容

// enumerator遍历器,可以通过for..in..遍历所有的子路径

NSDirectoryEnumerator *enumerator = [mgr enumeratorAtPath:file];

for (NSString *subpath in enumerator) {

// 获得全路径

NSString *fullSubpath = [file stringByAppendingPathComponent:subpath];

// 获得文件属性

NSDictionary *attrs = [mgr attributesOfItemAtPath:fullSubpath error:nil];

//        size += [attrs[NSFileSize] integerValue];

//      通过key直接取出来

size += attrs.fileSize;

}

第二种方式的原理:怎么获取一个文件夹内容的大小,把一个文件夹给我,有了文件夹路径,有了manager,然后获得一个可以获取文件夹路径的遍历器,它通过for...in...可以遍历出所有文件夹的子路径。通过子路径生成一个完整的路径(全路径),我就获取所有子路径文件的大小。把它所有的文件夹大小加起来,就是我们总文件的大小。


5 SDWebImage实现:

- (NSUInteger)getSize {

__block NSUInteger size = 0;

dispatch_sync(self.ioQueue, ^{

NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];

for (NSString *fileName in fileEnumerator) {

NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];

NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];

size += [attrs fileSize];

}

});

return size;

}

SDWebImage底层在这里是怎么实现:把一个文件夹传进去,获取所有的迭代器,从迭代器中获取所有的子路径通过文件夹路径拼接一个文件名变成一个全路径,然后再通过attributes这个属性累加起来;但是,它是直接调用字典这种方法(我们是前面是通过key取出来的),而且是放在一个自己创建的一个串行队列中去的,也就是异步的

但是现在放在viewDidLoad中算,肯定是有问题的,比较耗时,我们得修改

你可能感兴趣的:(23 手机上内存清理)