截止至本文時, 本文介紹的方法適用范圍: iOS8 ~ iOS14.5
一般來說, 我們在開發(fā)一些緩存或者app下載功能模塊的時候, 經(jīng)常會遇到這樣一個需求:
判斷手機的剩余存儲空間, 當空間不足的時候, 提示用戶空間不足
而網(wǎng)上搜索到的方法基本都是如下這種
- (CGFloat)freeDiskSpaceInBytes {
if (@available(iOS 11.0, *)) {
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:[self privatePath]];
NSError *err;
NSDictionary *results = [fileURL resourceValuesForKeys:@[NSURLVolumeAvailableCapacityForImportantUsageKey] error:&err];
if (!results) {
NSLog(@"Error retrieving resource keys: %@%@",[err localizedDescription], [err userInfo]);
abort();
} else {
CGFloat remain = [results[NSURLVolumeAvailableCapacityForImportantUsageKey] floatValue]/1000/1000;
return remain;
}
}
struct statfs buf;
unsigned long long freeSpace = -1;
if (statfs("/var", &buf) >= 0) {
freeSpace = (unsigned long long)(buf.f_bsize * buf.f_bavail);
}
CGFloat space = (CGFloat)(freeSpace*1.0/1024/1024);
return space;
}
這種方法獲取到的剩余存儲空間確實是 "準確" 的, 他和你手機->設(shè)置->關(guān)于本機里面能看到的那個數(shù)值是相等的.
然而, 手機設(shè)置里看到的剩余存儲空間的數(shù)值, 本身就是不準確的, 這真的是一個大坑
我實際開發(fā)的過程中發(fā)現(xiàn), 明明讀取到手機還有7.2g的剩余空間, 手機也顯示還有7.2g的剩余空間, 但是 spring_board經(jīng)常會莫名其妙crash, app應用也會出現(xiàn)一些異常的表現(xiàn), 比如莫名其妙的卡死和發(fā)燙.
后來發(fā)現(xiàn), 上述情況獲取到的, 只是一個系統(tǒng)的 "預估" 內(nèi)存, 并不是實時的可用物理空間大小
后來改用如下方案, 就可以實時獲取到真正的物理空間了
- (CGFloat)getNewFreeSize {
uint64_t totalSpace = 0;
uint64_t totalFreeSpace = 0;
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
CGFloat s = 0;
if (dictionary.count) {
NSNumber *fileSystemSizeInBytes = dictionary[NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = dictionary[NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
s = totalFreeSpace/ (1024.0 * 1024.0);
}
return s;
}
寫在最后: 我不知道是iOS13本身的問題還是蘋果所有系統(tǒng)版本的特性. 當我用下面這個相對準確的方法獲取物理存儲空間之后, 我發(fā)現(xiàn)隨著我不斷的寫入數(shù)據(jù), 他檢測到的可用空間大小是會波動的, 當程序持續(xù)執(zhí)行寫入的時候, 理論上可用空間會越來越小, 但是實際上我觀察發(fā)現(xiàn): 有好幾次空間已經(jīng)小于我設(shè)計的閾值500MB了, 過了一會兒竟然又反彈到500MB以上, 然后又慢慢變小. 因此感覺在持續(xù)寫入的過程中, 系統(tǒng)是會有一套類似LRU的策略, 去淘汰掉一些不用的碎片空間的.
當然, 以上這段話是我的猜測.
我是火球貓, 謝謝觀看我的文章, 有問題的話就留言吧.