設置界面中清除緩存的處理 (抄錄轉載)
www.lxweimin.com/p/1ee0761624a6
1
手機上的磁盤緩存 == 從網絡上下載的數據 + 寫入的數據
手機上的磁盤緩存的數據類型 == 圖片 + 多媒體文件(音頻/視頻)
它們存在于沙盒中
這里要清除緩存,就要拿到沙盒中存在的緩存的大小,就是看我們下載的圖片文件有多大,然后把它顯示在cell當中
因為我們下載圖片用到是SDWebImage框架,所以我們要獲取所下載圖片的緩存大小,最簡單的方法也是使用SDWebImage里面的東西--SDImageCache
2
獲取磁盤緩存的大小,它是一個單例,在mac和ios中,數據的大小不是以1024為單位的而是以1000為單位,不用弄混淆了
獲取沙盒路徑:
NSLog(@"%@",NSTemporaryDirectory());
單位是Mb
NSLog(@"%f",[SDWebImageCache sharedImageCache].getSize);
3沙盒結構
Documents 不允許存放大型文件,備份ITunes,緩存文件放這里邊,是不允許通過的
Library:存放緩存文件(整個緩存在default文件夾)和用戶偏好設置
temp:臨時變量
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中算,肯定是有問題的,比較耗時,我們得修改