博客 / 詳情

返回

百度APP iOS端磁盤優化實踐(上)

01 概覽

在APP的開發中,磁盤管理已成為不可忽視的部分。隨着功能的複雜化和數據量的快速增長,如何高效管理磁盤空間直接關係到用户體驗和APP性能。本文將結合磁盤管理的實踐經驗,詳細介紹iOS沙盒環境下的文件存儲規範,探討業務緩存、用户資產及系統緩存的清理策略。同時,分享自動清理與手動清理相結合的機制,展示如何在不同觸發條件下合理執行磁盤清理。文章使用文心一言輔助編寫。

02 磁盤系統介紹

2.1 ios沙盒系統

沙盒機制是iOS系統中的一種安全體系。每個iOS程序都有一個獨立的文件系統,而且只能在對應的文件系統中進行操作,此區域被稱之為沙盒(SandBox)。APP中所有文件都保存在此,如文本文件、圖片、圖標、媒體資源、Mach-O等。主要包含4個目錄 MyApp.app、Documents、Library、tmp。

MyApp.app目錄包含應用程序及其所有資源,即.ipa安裝包解壓後的.app內容,僅支持只讀訪問。Documents目錄用於存儲用户生成的內容,可以通過文件共享提供給用户,並由iCloud備份。Library目錄則用於存放非用户數據文件的頂級目錄,通常包含幾個標準子目錄,如Application Support和Caches,並由iCloud(Caches除外)備份。而tmp目錄用於寫入臨時文件,這些文件不需要在應用程序啓動之間保留,當不再需要時應由應用程序刪除,且不被iCloud備份。 圖片

2.2 獲取目錄API

NSSearchPathForDirectoriesInDomains()函數用於查找目錄,返回指定範圍內的指定名稱的目錄的路徑集合。

// 獲取沙盒主目錄路徑
NSString *homeDir = NSHomeDirectory();
// 獲取Documents目錄路徑
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// 獲取Library的目錄路徑
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
// 獲取Caches目錄路徑
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// 獲取tmp目錄路徑
NSString *tmpDir =  NSTemporaryDirectory();
//應用程序程序包的路徑
[[NSBundle mainBundle] bundlePath];

2.3 文件存儲規範

iOS項目開發中,文件管理至關重要。我們結合Apple官方指導與項目實踐,形成了一套詳細的文件使用規範。這些規範不僅遵循了iCloud備份策略,還充分考慮了文件類型特性和業務需求。結合業務使用場景,能夠更準確地判斷哪些文件是臨時數據、哪些是用户生成的重要文件,為後續進行磁盤監控和清理提供了便利。

MyApp.app:

  • 用途:應用程序的包,此目錄包含應用程序Mach-O可執行文件及其所有資源,iCloud默認不備份此目錄。
  • 使用規範:
  • 開發者不能寫入此目錄。寫入此目錄會影響簽名導致APP無法啓動。
  • 開發者可以獲得對應用程序包中存儲的任何資源的只讀訪問權限。

Documents:

  • 用途:存儲用户生成的內容的頂級目錄,iCloud默認備份此目錄。
  • 使用規範:
  • 該目錄應僅包含開發者可能希望向用户公開的文件。

Documents/Inbox:

  • 用途:存儲通過外部共享方式導入到APP的文件,iCloud默認備份此目錄。
  • 使用規範:
  • 開發者不應自行在此目錄下創建文件。
  • 開發者可讀可刪,將此目錄中文件移出後再編輯。

Library:

  • 用途:存儲非用户數據文件的頂級目錄,iCloud默認備份此目錄(Caches除外)。
  • 使用規範:
  • 可以創建自定義子目錄,用於保存不向用户公開的任何文件。
  • 各業務方需要創建業務相關的子目錄存儲數據。

Library/Caches:

  • 用途:用於存放再次下載或重新生成的數據,iCloud不會備份此目錄。
  • 使用規範:
  • 存放可以重新下載或生成的數據,如圖片緩存文件、臨時文件等。
  • 系統在系統儲存不足時可能會刪除該目錄以釋放磁盤空間。
  • 各業務數據緩存文件應放在/Library/Caches的子目錄下,方便管理。

Library/Application Support:

  • 用途:用於存儲APP配置和數據文件,iCloud默認備份此目錄。
  • 使用規範:
  • 存放程序配置和數據文件,如配置文件、模板等,不應存放緩存文件。
  • 避免在此目錄下創建不必要的文件,以減少備份時間和存儲空間佔用。

Library/Preferences:

  • 用途:用於存儲應用程序的首選項值,iCloud默認備份此目錄。
  • 存放建議:
  • 開發者不應自行在此目錄下創建文件。
  • NSUserDefaults或CFPreferences來獲取和設置APP的首選項值。

tmp:

  • 用途:用於存放臨時數據,iCloud不會備份此目錄。
  • 存放建議:
  • 僅存放臨時數據,開發者應在使用完這些文件後及時刪除。
  • 系統會清除目錄下文件,應用程序終止後可能不存在。
  • 不推薦業務方使用此目錄存放重要數據。

2.3.1 文件命名規則

  • 文件夾命名推薦Pascal命名法,第一個字母大寫。

  • 一個業務最多3個二級路徑:

  • 業務數據放在Library/下的一個目錄下。
  • 數據緩存文件放在Library/Caches的一個目錄下。
  • 用户數據放Documents/下的一個目錄下。

2.3.2 iCloud備份與恢復

iCloud會默認同步Documents、Library 目錄下的文件(Caches子目錄除外),用户在設置中開啓iCloud同步功能,同步APP數據時會上傳所有沙盒數據。如果沒有按照規範創建目錄,會導致大量緩存文件被上傳到iCloud,嚴重佔用用户iCloud 空間,嚴重時甚至會被Apple官方警告。如果將數據寫入這些目錄,但是又不希望同步到iCloud,iOS提供了API可以排除默認同步的目錄,需要開發者在創建文件時主動設置。

由於無法查看iCloud備份的沙盒文件內容,使用Mac本地備份的方式模擬iCloud備份行為。iPhone連接Mac,打開訪達,選擇將數據備份到Mac,恢復備份。測試發現Document文件夾下的子目錄和子文件,屬性被設置為NSURLIsExcludedFromBackupKey,恢復備份後不在,符合預期。不過用電腦備份和iCloud有個差異,Library/Caches下的文件也會被備份。

注意:此方法對於在App Store的應用,即使在恢復備份前將APP刪除,也會在恢復備份後自動下載APP,並且恢復數據。對於不在App Store的應用,比如我們的測試DemoAPP,在恢復備份前不要刪除DemoAPP,否則無法查看效果。因為無法下載不在Appstore的APP安裝包,所以備份內容也無法還原。測試APP在恢復備份後重新安裝就可以查看完整的沙盒文件。

  • API設置對於性能的損耗:
    iPhone12 :總計 14780 個文件,總計耗時 1124.180794 ms,平均每次耗時0.076ms
    iPhone6p:總計 11650 個文件,總計耗時 3730.319023 ms,平均每次耗時0.32ms
  • NSURLIsExcludedFromBackupKey不需要每次使用目錄或文件時都調用,只需要設置一次即可。設置屬性後,該目錄下所有子目錄和文件都不會同步到iCloud,但是子目錄和文件的屬性NSURLIsExcludedFromBackupKey依舊為NO。
  • 創建文件URL時需要調用[NSURL fileURLWithPath:] ,然後獲取和設置 NSURLIsExcludedFromBackupKey。
NSURL *pathurl = [NSURL fileURLWithPath:path];
BOOL success = NO;
success = [pathurl setResourceValue:@(YES) forKey:NSURLIsExcludedFromBackupKey error:nil];

2.4 磁盤大小計算方式

在系統中可以查看一個APP佔用磁盤大小,iPhone 存儲空間通常由APP 大小文稿數據大小組成。getResourceValue:forKey:error: 或者attributesOfItemAtPath:error: 直接獲取的是“文件大小”,不是文件佔用的磁盤物理空間。計算文件的磁盤佔用大小需要通過磁盤塊的方式。標準頭文件stat.h的st\_blocks可以獲取到塊的數量,st\_blocks * 512計算出文件的磁盤佔用大小。 扇區(block)是磁盤讀寫的最小物理單位。之所以扇區大小是 512 字節,這種做法源自較早的磁盤扇區大小標準。這種設計是基於早期磁盤技術的物理限制,儘管現代硬盤的物理扇區大小可能已經增加到了 4096 字節,但 512 字節的邏輯塊大小在許多文件系統和操作系統的接口中仍然被保留。iOS系統存儲單位為十進制,且保留有效小數機制為四捨五入。

圖片

+ (unsigned long long)fileSizeOnDisk:(nonnull NSString *)filePath {
struct stat fileStat;
int res = stat([filePath cStringUsingEncoding:NSUTF8StringEncoding], &fileStat);
if (-1 == res) {
return 0;
    }
long long fileSize = fileStat.st_blocks / 8 * fileStat.st_blksize;
return fileSize ;
}


2.5 APP包大小

APP包大小是手機沙盒的重要組成部分,包體積直接影響用户轉化率。用户可以在iPhone存儲空間設置中查看設備上各APP大小文稿與數據大小。

百度APP在iOS17系統的iPhone存儲空間設置中,系統不顯示APP大小,只有文稿與數據大小。經過調研,發現在iOS17系統APP使用ODR功能後,會導致APP大小被計算到了iOS系統數據。推測是iOS17系統BUG,iOS18系統已經恢復正常。

03 磁盤清理

在綜合性 APP 的開發中,多個業務方共同使用沙盒空間,磁盤緩存的管理面臨諸多挑戰。每個業務方對磁盤使用的整體感知較弱,難以準確評估自身的空間佔用大小是否合理,磁盤佔用很容易出現無限增長的問題。同時,不同業務方可能獨立設計了緩存清理策略,缺乏統一規範,難以滿足統一管理的需求。

為解決這些問題,從全局出發設計一套高效的磁盤清理方案。這套方案結合自動清理手動清理的機制,對磁盤使用進行統一管理。自動清理負責監測磁盤佔用情況,通過設置清理閾值和判斷條件,在空間不足時通知或觸發業務方執行清理操作。清理範圍以業務緩存為主,支持按業務個性化配置清理規則,確保管理靈活高效。手動清理則面向用户,提供簡單直觀的操作界面,允許用户自主選擇清理範圍,管理下載文件等數據,從而平衡自動化與用户自主權。

此外,在iOS平台上,系統本身具有定期清理臨時文件和部分緩存內容的機制。設計磁盤清理方案時,合理利用這些系統行為,同時避免依賴其不可控性。通過以上策略,可以在確保磁盤空間高效管理的同時,最大限度地保障用户體驗,為綜合性APP提供可靠的存儲管理支持。

圖片

3.1 自助清理

3.1.1 業務限額

為了管理和規範業務方對磁盤的使用,根據業務的使用場景和必要性,評估每個業務方需要使用的磁盤空間,每一個業務佔用的緩存大小會被分配一個限額,業務需要保證自身緩存佔用限制在限額以下。業務方從磁盤組件獲取業務自身限額值,保證自身緩存佔用在限額以內;而磁盤組件會從磁盤剩餘大小、APP已使用大小、業務使用頻率等條件實時分配合適的限額給各個業務方。

3.1.2 磁盤等級

根據設備的剩餘磁盤空間與應用程序所佔用的磁盤空間大小,我們可以將磁盤狀態細分 為Normal、Warning、以及Critical三個等級,每個等級都反映了用户磁盤空間的使用狀況。當處於Normal時,表明用户的手機尚擁有充裕的剩餘空間,且APP所佔用的磁盤空間相對較小。在此情境下,我們可以適度增加分配給各個業務方的限額,使得業務方有機會緩存更多內容,從而實現以空間換取時間的性能優化,進一步提升用户體驗。

然而,一旦進入Critical等級,意味着用户的手機剩餘空間已所剩無幾,或是 APP佔用了過多的空間。這種情況下,用户的手機很容易出現卡頓現象,甚至面臨存儲空間告急的困境。更為嚴重的是,這可能會迫使用户做出卸載APP的極端選擇。因此,在Critical等級下,我們必須對業務方使用磁盤空間的行為進行嚴格限制,並強制要求業務方徹底清理任何不必要的緩存,以確保用户的手機能夠維持基本的運行需求。

3.1.3 狀態檢測

磁盤狀態檢測是磁盤組件的核心功能,檢測 APP 運行期間設備磁盤的使用情況,判斷是否需要觸發自動清理操作。APP 啓動後周期性的執行磁盤使用狀態檢查,自動觸發相應的清理機制。通過不同條件觸發磁盤清理,以優化應用性能並提升用户體驗。為此設計了多種觸發清理機制的機制,確保不同情況下都能觸發清理操作:

等級:根據磁盤使用等級的變化來決定是否清理;

版本:如果應用版本發生升級,會強制業務方執行一次清理。 時間:根據磁盤等級設定兜底的定期清理間隔。

3.1.4 觸發清理

業務方在各自的組件中註冊磁盤清理回調protocol,不同的業務模塊能夠響應磁盤等級變化並進行相應的處理,實現了磁盤清理服務與業務模塊之間的解耦合。業務在收到磁盤狀態等級變化時,重新查詢業務限額,並調整自身策略,管控和優化自身佔用緩存,保證保證自身緩存佔用在限額以內。

磁盤組件會逐一調用各業務模塊註冊的清理回調,通過protocol抽象各模塊的清理邏輯,實現了對多業務模塊的統一管理和擴展性支持。結合信號量機制實現同步等待,確保每個模塊的清理任務按順序完成。所有清理任務完成後,磁盤組件會觸發全局回調進行狀態更新。

3.2 手動清理

手動清理沿用自動清理的設計思路,業務方實現清理協議,註冊到磁盤組件,然後由磁盤組件統一管控。和自動清理不同的是,手動清理提供了一個用户可視化頁面,並且詳細列出可清理的內容供用户選擇。支持深度清理,在大多數情況下,業務邏輯要求清除所有緩存數據。除此之外,還另外添加了用户資產管理功能。

3.2.1 用户資產管理

用户資產定義為用户自主下載並保存的各類文件,包括但不限於視頻、圖片、安裝包、PDF 文檔、Excel 表格以及 Word 文件等。百度APP是一個綜合性 APP ,兼具瀏覽器的功能。用户在瀏覽網頁的過程中,會下載各種內容。特別是在 iOS 設備上,用户還可能會下載一些無法安裝的安裝包。儘管這些文件是用户主動下載的,但實際上它們可能並無實際用途,且長期佔用用户的磁盤空間。用户資產管理模塊可以幫助用户輕鬆地識別並清理那些不再需要或無效的用户資產,從而有效釋放存儲空間,提升設備的整體性能。

3.3 系統緩存清理

3.3.1 tmp目錄

iOS的tmp目錄是系統緩存目錄,Apple官方文檔的説明是使用此目錄寫入不需要在APP啓動之間保留的臨時文件。當不再需要文件時,APP應從該目錄中刪除這些文件,系統也可能會在APP未使用時清除此目錄。實際使用過程中發現,依賴系統清理該文件夾具有不可控性,因此需要對該文件夾進行清理,tmp目錄主要包含以下文件:

圖片

1. 下載緩存文件

NSURLSessionDownloadTask進行文件下載的過程中,系統為了確保數據的完整性和安全性,會在文件下載完成前,將其暫時保存在以.tmp為擴展名的臨時文件中。這些臨時文件的命名遵循CFNetworkDownload\_xxxx.tmp的格式,其中CFNetworkDownload\_是固定的前綴,而後續的xxxx部分則根據每個下載任務的不同而有所區別。

NSURLSessionConfiguration配置會導致這些臨時文件被存儲在沙盒的不同位置。defaultSessionConfiguration創建的下載任務,其臨時文件會被保存在沙盒的tmp文件夾內。backgroundSessionConfiguration,臨時文件的存儲位置則有所不同。在後台下載模式下,為確保即使應用進入後台,下載任務也能繼續進行。這些文件會存放在Library/Caches/com.apple.nsurlsessiond/Downloads/<bundle_id>。

然而,需要注意的是,沙盒中的tmp文件夾主要用於存放臨時文件,這些文件在磁盤空間不足時可能會被系統自動清理。因此,如果下載任務被取消,且臨時文件沒有被及時移動到其他安全的存儲位置,它們可能會因為 tmp 文件夾的清理機制而被刪除。這將導致用户無法從上次中斷的位置繼續下載,即無法實現斷點續傳。

2. tmp目錄清理

統計tmp目錄下可以被清理的文件,可以選擇全部清理,也可以按照業務實際應用場景,選擇過期清理等方案。

/// 統計 /tmp 目錄下需要清理的緩存文件
+ (NSArray<NSURL *> *)calculateTmpSysCache {
// 匹配文件名的模式
NSArray *regexPatterns = @[@"CFNetworkDownload", @"WKWebFileUpload", @"NSIRD_", @"正在存儲文稿"];
NSString *tmpPath = NSTemporaryDirectory();
if (!tmpPath) return @[];
NSMutableArray *tmpNeedCleanCache = [NSMutableArray array];
NSFileManager *fileManager = [NSFileManager defaultManager];
for (NSString *fileName in [fileManager enumeratorAtPath:tmpPath]) {
NSString *fullPath = [tmpPath stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:fullPath];
// 檢查是否符合清理條件
if ([self shouldCleanFile:fullPath patterns:regexPatterns]) {
            [tmpNeedCleanCache addObject:fileURL];
        }
    }
return tmpNeedCleanCache;
}

3.3.2 WKWebView清理

WKWebView是iOS和MacOS上用於加載和展示網頁內容的控件,它利用了多種緩存機制來提升加載速度和用户體驗。以下是WKWebView緩存產生的幾個主要原因:

  • 資源緩存(HTTP 緩存):WKWebView會緩存通過網絡請求加載的網頁資源(如 HTML、CSS、JS、圖片等),以減少重複下載,提升網頁的加載速度。這些資源通常存儲在本地磁盤上。
  • Cookie 緩存:網站使用的Cookie會被WKWebView緩存,用於維護會話狀態、用户登錄信息等。
  • Session Storage和Local Storage:WKWebView支持HTML5的sessionStorage和localStorage,用於本地存儲網站數據,以便後續訪問時能夠直接從緩存中讀取,而無需重新下載。
  • WebKit Cache(WebKit內部緩存):WebKit內部有一套複雜的緩存系統,用於管理各種網頁資源、腳本、圖像等的緩存。WKWebView依賴這些機制來加速網頁內容加載。
  • Service Workers和離線緩存:一些網頁使用Service Workers來實現離線功能或加速加載特定資源,WKWebView會緩存這些資源,以便在後續使用時能夠從本地獲取。

1. WKWebView緩存清理方法

清理指定數據類型的緩存:通過WKWebsiteDataStore可以清理特定類型的緩存,比如Cookies、緩存、localStorage等。該方法可以清理指定類型的緩存數據,並支持自定義時間範圍。以下代碼展示瞭如何清理WKWebView的緩存數據:

// 獲取所有類型的緩存
NSSet *websiteDataTypes = [NSSet setWithArray:@[
WKWebsiteDataTypeCookies,                 // Cookie
WKWebsiteDataTypeLocalStorage,            // localStorage
WKWebsiteDataTypeIndexedDBDatabases,      // IndexedDB
WKWebsiteDataTypeWebSQLDatabases,         // WebSQL
WKWebsiteDataTypeFetchCache,              // Fetch API
WKWebsiteDataTypeDiskCache,               // 磁盤緩存
WKWebsiteDataTypeMemoryCache,             // 內存緩存
WKWebsiteDataTypeOfflineWebApplicationCache // 離線應用緩存
]];
// 獲取過去時間的日期,比如一個月前
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
// 清理特定類型的數據
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes
                                           modifiedSince:dateFrom
                                       completionHandler:^{
NSLog(@"清理緩存完成");
}];

清理指定域名的數據如果只想清理某個特定網站的緩存,可以通過查詢 WKWebsiteDataRecord 來實現:

// 獲取指定域名的數據
[[WKWebsiteDataStore defaultDataStore] fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
                                             completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
for (WKWebsiteDataRecord *record in records) {
if ([record.displayName containsString:@"example.com"]) { // 指定域名
            [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:record.dataTypes
                                                       forDataRecords:@[record]
                                                    completionHandler:^{
NSLog(@"清理 %@ 的緩存完成", record.displayName);
            }];
        }
    }
}];

2. WKWebView清理實踐

在WKWebView的清理實踐中,先計算NetworkCache文件夾的大小,一旦超過設定的限制即會觸發清理流程。在清理過程中,為了保證緩存帶來的性能優化和磁盤空間佔用達到平衡,我們並沒有選擇全部刪WKWebView的所有緩存,而是按照文件的修改日期進行排序,確保最老的文件在後續的清理中會被優先處理。

+ (void)cleanUpWKWebViewCacheWithLimit {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC * SOME_DELAY)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 設置緩存上限為10MB
unsigned long long cacheLimit = SOME_CACHE_LIMIT;
// 獲取WebKit網絡緩存目錄
NSString *networkCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Caches/WebKit/NetworkCache"];
// 計算緩存總大小
unsigned long long totalSize = [self calculateDirectorySize:networkCachePath];
if (totalSize < cacheDiskLimit) {
return;
        }
// 獲取Records子目錄路徑
NSString *networkCacheRecordsPath = [networkCachePath stringByAppendingPathComponent:@"/Version 16/Records"];
// 獲取所有文件列表,安時間排序判斷需要清理的文件
NSArray *filelist = [self listFilesInDirectory:networkCacheRecordsPath];
if (filelist.count == 0) {
return;
        }
if (@available(iOS 9.0, *)) {
dispatch_async(dispatch_get_main_queue(), ^{
WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
NSSet *dataTypes = [NSSet setWithArray:@[WKWebsiteDataTypeDiskCache]];
                [dataStore removeDataOfTypes:dataTypes modifiedSince:SOME_DAY_AGO completionHandler:^{
// 清理完成
                }];
            });
        }
    });
}

3.3.3 dyld緩存清理

dyld是iOS和MacOS系統中的一個關鍵組件,負責在程序啓動時加載和鏈接動態庫(如框架和共享庫)。在iOS 13及更早版本中,dyld可能會在tmp目錄下創建一些臨時緩存文件,用於加速後續的程序啓動過程。這些緩存文件包含了動態庫的加載信息,使得系統在下次啓動相同程序時能夠更快地找到並加載所需的庫。

然而,iOS13系統之前會在每次APP升級後的首次啓動生成一個新的dyld緩存,保存在tmp/com.apple.dyld,並且之前的APP版本的dyld緩存也不會自動刪除。該部分緩存會隨着版本升級不斷累加,需要管理這部分緩存,實際上還有部分用户從 iOS13 系統升級到更高系統,這部分緩存就會一直遺留在用户手機中,高達上百 MB。iOS14 系統則是遷移到了Library/Caches/com.apple.dyld,且系統會自動清理。

/// 清理iOS13系統生成的tmp/com.apple.dyld緩存文件
+ (void)cleanTmpDyld {
NSString *tmpDyldPath = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/com.apple.dyld"];
if ([[NSFileManager defaultManager] fileExistsAtPath:tmpDyldPath]) {
// 系統版本大於iOS14
if (@available(iOS 14.0, *)) {
            [PFMDiskSizeUtils cleanupDirectoryAtPath:tmpDyldPath];
        } else {
// 保留計數限制為 1,保留最新的
            [PFMDiskSizeUtils cleanDiskCaches:tmpDyldPath reservedCountLimit:1];
        }
    }
}

3.3.4 其他系統緩存清理

  • Documents/Inbox是iOS應用接收文件的默認目錄,直接清理即可;
  • Library/Preferences目錄下屬於應用的臨時 .plist 文件。這些文件通常由 NSUserDefaults自動生成,有時在寫入或更新過程中會生成臨時文件。
/// 清除 Documents/Inbox 目錄
+ (void)cleanUpInboxPath {
NSString *inboxPath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/Inbox"];
if (inboxPath) {
        [PFMDiskSizeUtils cleanupDirectoryAtPath:inboxPath];
    }
}

/// 清除 Library/Preferences/bundleId.plist.xxxx文件
+ (void)cleanUpUserDefaultsTempPlistFiles {
NSString *preferencesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Preferences"];
NSDirectoryEnumerator *dirEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:preferencesPath];
NSString *deleteFilePrefix = [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".plist."];
NSString *file;
while (file = [dirEnumerator nextObject]) {
if ([file hasPrefix:deleteFilePrefix]) {
NSString *deleteFilePath = [preferencesPath stringByAppendingPathComponent:file];
NSDate *fileModifyDate =  [[[NSFileManager defaultManager] attributesOfItemAtPath:deleteFilePath error:nil] objectForKey:NSFileModificationDate ];
            [PFMDiskSizeUtils cleanupDirectoryAtPath:deleteFilePath];
        }
    }
}

04 總結

本篇文章圍繞百度APP的磁盤清理問題,從iOS沙盒文件存儲機制出發,系統性地闡述了磁盤管理的重要性和技術實現。文章探討了自動清理與手動清理的結合策略,通過多維度觸發機制和靈活的用户交互設計,平衡了系統性能與用户體驗。後續我們還會分享磁盤監控和磁盤異常問題治理相關的文章。

————END————

推薦閲讀

讀友好的緩存淘汰算法

如何定量分析 Llama 3,大模型系統工程師視角的 Transformer 架構

微服務架構革新:百度Jarvis2.0與雲原生技術的力量

技術路線速通!用飛槳讓京劇人物照片動起來

無需業務改造,一套數據庫滿足 OLTP 和 OLAP,GaiaDB 發佈並行查詢能力

user avatar devil_5931bede13754 頭像
1 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.