需求
緩存計(jì)算、緩存清理帜讲。
技術(shù)點(diǎn)
沙盒是什么
沙盒簡單來說就是一個(gè)應(yīng)用程序獨(dú)有的存儲和讀取內(nèi)容的地方衅谷,這個(gè)地方本身就是一個(gè)文件夾似将。
每個(gè)應(yīng)用程序都有自己的沙盒获黔,只能訪問自己的玩郊,不能訪問別人的(訪問別人的需要權(quán)限)肢执。
沙盒文件夾的區(qū)別
如上圖译红,應(yīng)用程序沙盒目錄下有三個(gè)文件夾Documents预茄、Library(下面有Caches和Preferences目錄)侦厚、tmp耻陕。
- Documents:可用于保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù)刨沦,開發(fā)中一般會將需要持久化存儲的東西存這里诗宣,比如數(shù)據(jù)庫文件想诅。iTunes會自動備份該目錄召庞。
- Library/Caches:可用于存儲緩存文件,例如圖片視頻等篮灼,著名的SDWebImage框架就將緩存的圖片放在這個(gè)地方忘古。iTunes不會備份該目錄。
- Library/Preferences:保存應(yīng)用程序的所有偏好設(shè)置iOS的Settings(設(shè)置)髓堪。不應(yīng)該直接在這里創(chuàng)建文件,而是需要通過NSUserDefault這個(gè)類來訪問娘荡,換句話說干旁,NSUserDefault類存儲的文件會被寫進(jìn)這個(gè)文件夾炮沐。iTunes會自動備份該文件目錄下的內(nèi)容争群。
- tmp:臨時(shí)文件目錄央拖,當(dāng)應(yīng)用程序未運(yùn)行時(shí)祭阀,系統(tǒng)可能會清除此目錄鲜戒,一般用于保存應(yīng)用程序再次啟動時(shí)不需要的信息专控。
代碼
獲取文件夾路徑
- 獲取Documents路徑
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
- 獲取Library路徑
NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
- 獲取Library/Caches路徑
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
- 獲取Library/Preferences路徑
NSString *path = [NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES) firstObject];
- 獲取tmp路徑
NSString *path = NSTemporaryDirectory();
緩存計(jì)算
思路
開發(fā)過程中根據(jù)實(shí)際情況遏餐,看看具體要計(jì)算哪個(gè)文件夾的大小,又或者哪個(gè)文件不需要算入緩存大小(比如數(shù)據(jù)庫文件我就不算進(jìn)緩存)失都;
需要注意的是柏蘑,如果用了一些緩存框架,要弄清楚它存儲的路徑粹庞,不能手動去刪緩存,要用框架提供的接口刪庞溜,例如SDWebImage就提供了獲取大小接口[SDImageCache sharedImageCache].getSize
和清理緩存接口[[SDImageCache sharedImageCache] clearDisk]革半。(前文提到過,SDWebImage會在Library/Caches下建一個(gè)自己的文件夾流码,它的接口當(dāng)然也只會操作它自己的文件夾);
根據(jù)我的習(xí)慣漫试,一般我會把數(shù)據(jù)庫文件等東西存于Documents中六敬,并使用SDImageCache緩存圖片,所以緩存計(jì)算時(shí)驾荣,我會計(jì)算Documents的大小(不計(jì)算其中的數(shù)據(jù)庫文件)和SDImageCache的緩存大小普泡。計(jì)算某個(gè)文件或文件夾的大小的代碼
//計(jì)算結(jié)果
int totalSize = 0;
// 構(gòu)建需要計(jì)算大小的文件或文件夾的路徑,這里以Documents為例
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// 1.獲得文件夾管理者
NSFileManager *mgr = [NSFileManager defaultManager];
// 2.檢測路徑的合理性
BOOL dir = NO;
BOOL exits = [mgr fileExistsAtPath:path isDirectory:&dir];
if (!exits) return 0;
// 3.判斷是否為文件夾
if (dir)//文件夾, 遍歷文件夾里面的所有文件
{
//這個(gè)方法能獲得這個(gè)文件夾下面的所有子路徑(直接\間接子路徑),包括子文件夾下面的所有文件及文件夾
NSArray *subPaths = [mgr subpathsAtPath:path];
//遍歷所有子路徑
for (NSString *subPath in subPaths)
{
//拼成全路徑
NSString *fullSubPath = [path stringByAppendingPathComponent:subPath];
BOOL dir = NO;
[mgr fileExistsAtPath:fullSubPath isDirectory:&dir];
if (!dir)//子路徑是個(gè)文件
{
//如果是數(shù)據(jù)庫文件典勇,不加入計(jì)算
if ([subPath isEqualToString:@"mySql.sqlite"])
{
continue;
}
NSDictionary *attrs = [mgr attributesOfItemAtPath:fullSubPath error:nil];
totalSize += [attrs[NSFileSize] intValue];
}
}
totalSize = totalSize / (1024 * 1024.0);//單位M
}
else//文件
{
NSDictionary *attrs = [mgr attributesOfItemAtPath:path error:nil];
totalSize = [attrs[NSFileSize] intValue] / (1024 * 1024.0);//單位M
}
緩存清理
- 思路
根據(jù)開發(fā)中存儲位置的實(shí)際情況進(jìn)行數(shù)據(jù)清理叮趴。 - 清理某個(gè)文件或文件夾的內(nèi)容的代碼
//清理結(jié)果的信息
NSString *message = nil;//提示文字
BOOL clearSuccess = YES;//是否刪除成功
NSError *error = nil;//錯(cuò)誤信息
//構(gòu)建需要?jiǎng)h除的文件或文件夾的路徑割笙,這里以Documents為例
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//拿到path路徑的下一級目錄的子文件夾
NSArray *subPathArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
for (NSString *subPath in subPathArray)
{
//如果是數(shù)據(jù)庫文件,不做操作
if ([subPath isEqualToString:@"mySql.sqlite"])
{
continue;
}
NSString *filePath = [path stringByAppendingPathComponent:subPath];
//刪除子文件夾
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
if (error)
{
message = [NSString stringWithFormat:@"%@這個(gè)路徑的文件夾刪除失敗了",filePath];
clearSuccess = NO;
}
else
{
message = @"成功了";
}
}