1.哪些東西需要做緩存?
經(jīng)常改變的數(shù)據(jù)不需要做緩存,不變的數(shù)據(jù)才需要做緩存
圖片和微博界面的微博數(shù)據(jù)等,一般都不會改變,需要緩存
2.項目中有哪些控件或框架默認(rèn)幫我們做了一些緩存處理?
WKWebView系統(tǒng)做了緩存,SDWebImage
3.我們來到沙盒路徑下SDWebImage緩存目錄,發(fā)現(xiàn)里面的圖片名稱很特別,怎么處理的?
首先,我們知道如果存在同名的文件,后存入的文件會把之前的覆蓋掉
為了防止被覆蓋,一般都會對文件做加密處理
4.為什么要加密?
加密就是對緩存文件處理得到不同的文件名,防止被覆蓋
5.怎么加密?
一般來說對緩存文件加密有兩種方式
1.拿到文件二進(jìn)制數(shù)據(jù),先base64加密,然后再對加密得到的文本文件進(jìn)行MD5加密 得到的散列值 作為文件的名稱
2.直接對url進(jìn)行MD5加密,散列值作為文件名稱(SDWebImage就是這種方式)
6.如果兩個不同的url指向相同的圖片,采用上面第一種方法加密,得到的散列值是相同的 怎么辦?
這個時候我們可以在進(jìn)行MD5加密之前 對文本文件加鹽(日期,url,隨機(jī)數(shù)都可以作為鹽),這樣得到的散列值就不同了
7.怎么獲取緩存尺寸(大小)?
如果不會做緩存處理,那么我們可以查看SDWebImage怎么做緩存處理的
進(jìn)入 SDImageCache.h查看框架里面怎么處理的,我們發(fā)現(xiàn)很多方法來處理緩存
- (void)storeImage:(UIImage *)image forKey:(NSString *)key;
- (void)clearDisk; 清理磁盤緩存
- (void)cleanDisk; 清理過期的磁盤緩存
- (NSUInteger)getSize; 得到緩存的尺寸
其它方法可以自己去頭文件自己去查看,學(xué)習(xí)(有一份文頂頂翻譯的SDWebImage可以幫助我們學(xué)習(xí))
我們可以根據(jù)框架得到緩存尺寸的方法,模仿一個自己的方法
8.怎么模仿?
跳進(jìn)去- (NSUInteger)getSize;方法里面,分析方法怎么實現(xiàn)的 然后模仿
>//獲得磁盤緩存文件的總大小 - (NSUInteger)getSize {
__block NSUInteger size = 0;
//同步+串行隊列:在當(dāng)前線程中執(zhí)行block中的代碼
dispatch_sync(self.ioQueue, ^{
//得到diskCachePath路徑下面的所有子路徑
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
//遍歷得到所有子路徑對應(yīng)文件的大小旁涤,并累加以計算所有文件的總大小
for (NSString *fileName in fileEnumerator) {
//拼接文件的全路徑
NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
//獲得指定文件的屬性字典
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
//累加文件的大小 調(diào)用fileSize 獲得文件的大小 == attrs["NSFileSzie"]
size += [attrs fileSize];
}
});
return size;}
9.分析之后我們總結(jié)獲取緩存尺寸的步驟
9.1 創(chuàng)建文件管理者對象
9.2 根據(jù)一個路徑獲取該路徑下所有文件
9.3 遍歷所有文件
9.4 拼接文件的全路徑
9.5 獲取文件屬性
9.6 把每一個文件的尺寸(大小)累加起來 就是緩存的大小
我們只要把路徑改一下,就能獲取指定文件夾的尺寸(大小)
// 獲取SDWebImage緩存尺寸
-(void)getSize
{
// 獲取文件夾路徑
NSString *cachePath = XTCachePath;
NSString *defaultPath = [XTCachePath
stringByAppendingPathComponent:@"default"];
NSInteger totalSize = 0;
// 1.獲取文件管理者對象
NSFileManager *mgr = [NSFileManager defaultManager];
// 2.獲取所有文件(傳遞文件夾路徑)
// Path:文件夾路徑
// subpathsAtPath:獲取一個文件夾中所有子路徑,包含多級路徑
NSArray *subPaths = [mgr subpathsAtPath:defaultPath];
// 3.遍歷所有文件
for (NSString *subPath in subPaths) {
// 4.拼接完整文件名
NSString *filePath = [defaultPath stringByAppendingPathComponent:subPath];
// 判斷下是否是隱藏文件
if ([subPath hasPrefix:@".DS"]) continue;
// 是否是文件夾
BOOL isDirectory;
// 判斷文件是否存在,并且是否是文件夾
[mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (isDirectory) continue;
// 5.attributesOfItemAtPath:傳入文件全路徑,就能獲取文件屬性
NSDictionary *attr = [mgr attributesOfItemAtPath:filePath error:nil];
// 6.把文件尺寸累加
totalSize += [attr fileSize];
}
}
10.return break continue 的區(qū)別
return:直接跳出當(dāng)前方法
break:直接跳出當(dāng)前循環(huán)
continue:直接跳出本次循環(huán),進(jìn)入下一輪循環(huán)中
11.怎么把緩存大小展示到界面?
11.1首先我們先了解文件大小的單位換算
在電腦上:1M = 1024KB 1KB = 1024B
在手機(jī)上:1M = 1000KB 1KB = 1000B
11.2我們可以先定義一個字符串用來拼接緩存大小
系統(tǒng)返回的緩存大小以 B 為單位
我們需要展示最后的格式為: 清除緩存(xxx B) 或 清除緩存(xx.x KB) 或 清除緩存(xx.x M)
1.拿到緩存大小
2.判斷是否大于 1000 * 1000 大于的話就用 totalSize(緩存大小) / (1000 * 1000) 保留一位小數(shù)
拿到得到的結(jié)果 拼接成清除緩存(xx.x M)
3.判斷是否大于 1000 大于的話就用 totalSize(緩存大小) / 1000 保留一位小數(shù)
拿到得到的結(jié)果 拼接成清除緩存(xx.x KB)
4.都不滿足上面條件 就直接拿totalSize拼接成 清除緩存(xx.x KB)
5.然后把 .0 替換為空
- (NSString *)cacheStr
// 計算Cache緩存尺寸
NSInteger cacheSize = [self getSizeOfDirectoryPath:XMGCachePath];
CGFloat cacheSizeF;
NSString *sizeStr = @"清除緩存";
if (cacheSize > 1000 * 1000) { // MB
cacheSizeF = cacheSize / (1000.0 * 1000.0);
sizeStr = [NSString stringWithFormat:@"%@(%.1fMB)",sizeStr,cacheSizeF];
} else if (cacheSize > 1000) { // KB
cacheSizeF = cacheSize / 1000.0;
sizeStr = [NSString stringWithFormat:@"%@(%.1fKB)",sizeStr,cacheSizeF];
} else if (cacheSize > 0) { // B
sizeStr = [NSString stringWithFormat:@"%@(%ldB)",sizeStr,cacheSize];
}
把.0 替換為空
sizeStr = [sizeStr stringByReplacingOccurrencesOfString:@".0" withString:@""];
return sizeStr;
}
12.怎么清除緩存?
查看SDWebImage清除緩存的方法,我們可以總結(jié)清除緩存的步驟
1.創(chuàng)建文件管理者
2.刪除指定路徑下的文件夾
3.創(chuàng)建一個空的文件夾
注意:我們清除緩存后一定要刷新表格,才能讓展示的緩存數(shù)據(jù)實時更新
// 點擊cell就會調(diào)用
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 清空緩存
NSFileManager *mgr = [NSFileManager defaultManager];
// 1.刪除Cache文件夾
[mgr removeItemAtPath:XMGCachePath error:nil];
// 2.創(chuàng)建新Cache文件夾
[mgr createDirectoryAtPath:XMGCachePath withIntermediateDirectories:YES attributes:nil error:nil];
// 刷新表格 全局刷新
[self.tableView reloadData]; }
// 局部刷新(動畫刷新)(刪除指定行并刷新)
NSArray *indexPaths = @[[NSIndexPath indexPathForRow:0 inSection:0]];
//插入指定行并刷新
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
NSArray *indexPaths = @[
[NSIndexPath indexPathForRow:0 inSection:0],
[NSIndexPath indexPathForRow:1 inSection:0]
];
//刪除指定行并刷新
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationMiddle];
//刷新指定行
self.tableView reloadRowsAtIndexPaths:<#(nonnull NSArray<NSIndexPath *> *)#> withRowAnimation:<#
(UITableViewRowAnimation)#>