百度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 文件命名規則

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:websiteDataTypesmodifiedSince:dateFromcompletionHandler:^{
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.dataTypesforDataRecords:@[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 發布并行查詢能力

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66811.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66811.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66811.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker安裝elk6.7.1-搜集java日志

docker安裝elk6.7.1-搜集java日志 如果對運維課程感興趣&#xff0c;可以在b站上、A站或csdn上搜索我的賬號&#xff1a; 運維實戰課程&#xff0c;可以關注我&#xff0c;學習更多免費的運維實戰技術視頻 0.規劃 192.168.171.130 tomcat日志filebeat 192.168.171.131 …

SpringBoot的Swagger配置

一、Swagger配置 1.添加依賴 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version> </dependency> 2.修改WebMvcConfig Slf4j Configurat…

linux+docker+nacos+mysql部署

一、下載 docker pull mysql:5.7 docker pull nacos/nacos-server:v2.2.2 docker images 二、mysql部署 1、創建目錄存儲數據信息 mkdir ~/mysql cd ~/mysql 2、運行 MySQL 容器 docker run -id \ -p 3306:3306 \ --name mysql \ -v $PWD/conf:/etc/mysql/conf.d \ -v $PWD/…

代碼隨想錄——二叉樹(一)

文章目錄 二叉樹遍歷先序遍歷中序遍歷后序遍歷層序遍歷層序遍歷Ⅱ二叉樹的右視圖二叉樹的層平均值N插樹的層序遍歷在每個樹行中找最大值填充每個節點的下一個右側節點指針填充每個節點的下一個右側節點指針 II 二叉樹遍歷 先序遍歷 二叉樹先序遍歷 遞歸形式 /*** Definitio…

詳細介紹:持續集成與持續部署(CI/CD)技術細節(關鍵實踐、CI/CD管道、優勢與挑戰)

目錄 前言1、 持續集成&#xff08;CI&#xff09;1.1、持續集成的關鍵實踐1.2、持續集成工具1.3、持續集成的優勢 2、持續部署與持續交付&#xff08;CD&#xff09;2.1、持續交付&#xff08;Continuous Delivery&#xff09;2.2、持續部署&#xff08;Continuous Deployment…

Linux 系統服務開機自啟動指導手冊

一、引言 在 Linux 系統中&#xff0c;設置服務開機自啟動是常見的系統配置任務。本文檔詳細介紹了多種實現服務開機自啟動的方法&#xff0c;包括 systemctl 方式、通用腳本方式、crontab 方案等&#xff0c;并提供了生產環境下的方案建議和開機啟動腳本示例。 二、systemct…

Java如何向http/https接口發出請求

用Java發送web請求所用到的包都在java.net下&#xff0c;在具體使用時可以用如下代碼&#xff0c;你可以把它封裝成一個工具類 import javax.net.ssl.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Outpu…

禁止 iOS 系統瀏覽器雙指放大頁面

網上找到禁止ios縮放的方法基本都試過了,但是還是有bug,如標題所示,下面我將總結一下禁止ios縮放,雙擊縮放的方法。 方法一 在 iOS 10之前&#xff0c;iOS 和 Android 都可以通過一行 meta 標簽來禁止頁面縮放&#xff1a; <meta content"widthdevice-width, initia…

讀西瓜書的數學準備

1&#xff0c;高等數學&#xff1a;會求偏導數就行 2&#xff0c;線性代數&#xff1a;會矩陣運算就行 參考&#xff1a;線性代數--矩陣基本計算&#xff08;加減乘法&#xff09;_矩陣運算-CSDN博客 3&#xff0c;概率論與數理統計&#xff1a;知道啥是隨機變量就行

PLC通信

PLC&#xff08;可編程邏輯控制器&#xff09;通信是指 PLC 與其他設備或系統之間進行數據傳輸和信息交換的過程 一、PLC通信方式 1 &#xff09;串行通信 數據按位順序依次傳輸&#xff0c;只需要一對傳輸線&#xff0c;成本低&#xff0c;傳輸距離長&#xff0c;但速度相對…

C/C++、網絡協議、網絡安全類文章匯總

&#x1f6f8; 文章簡介 本文章主要對本博客的所有文章進行了匯總&#xff0c;方便查找。內容涉及C/C編程&#xff0c;CMake、Makefile、Shell腳本&#xff0c;GUI編程框架MFC和QT&#xff0c;Git版本控制工具&#xff0c;網絡協議基礎知識&#xff0c;網絡安全領域相關知識&a…

java 中多線程、 隊列使用實例,處理大數據業務

場景&#xff1a; 從redis 訂閱數據 調用線程來異步處理數據 直接上代碼 定義線程管理類 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org…

【自動駕駛】4 智駕生態概述

目錄 1 智駕生態概述 ▲ 關鍵組成部分 ▲ 概述 2 關鍵技術 ▲ 傳感器 ▲ 感知 ▲ 數據閉環 3 未來市場 1 智駕生態概述 智能駕駛生態&#xff0c;簡稱智駕生態&#xff0c;是指圍繞智能駕駛技術的開發、應用、服務和支持所形成的產業體系和合作網絡。 涵蓋了從硬件設…

2025.1.20——一、[RCTF2015]EasySQL1 二次注入|報錯注入|代碼審計

題目來源&#xff1a;buuctf [RCTF2015]EasySQL1 目錄 一、打開靶機&#xff0c;整理信息 二、解題思路 step 1&#xff1a;初步思路為二次注入&#xff0c;在頁面進行操作 step 2&#xff1a;嘗試二次注入 step 3&#xff1a;已知雙引號類型的字符型注入&#xff0c;構造…

”彩色的驗證碼,使用pytesseract識別出來的驗證碼內容一直是空“的解決辦法

問題&#xff1a;彩色的驗證碼&#xff0c;使用pytesseract識別出來的驗證碼內容一直是空字符串 原因&#xff1a;pytesseract只識別黑色部分的內容 解決辦法&#xff1a;先把彩色圖片精確轉換成黑白圖片。再將黑白圖片進行反相&#xff0c;將驗證碼部分的內容變成黑色&#…

Unity3D項目開發中的資源加密詳解

前言 在Unity3D游戲開發中&#xff0c;保護游戲資源不被非法獲取和篡改是至關重要的一環。資源加密作為一種有效的技術手段&#xff0c;可以幫助開發者維護游戲的知識產權和安全性。本文將詳細介紹Unity3D項目中如何進行資源加密&#xff0c;并提供相應的技術詳解和代碼實現。…

RabbitMQ 在實際應用時要注意的問題

1. 冪等性保障 1.1 冪等性介紹 冪等性是數學和計算機科學中某些運算的性質,它們可以被多次應?,?不會改變初始應?的結果. 應?程序的冪等性介紹 在應?程序中,冪等性就是指對?個系統進?重復調?(相同參數),不論請求多少次,這些請求對系統的影響都是相同的效果. ?如數據庫…

AIGC視頻生成明星——Emu Video模型

大家好&#xff0c;這里是好評筆記&#xff0c;公主號&#xff1a;Goodnote&#xff0c;專欄文章私信限時Free。本文詳細介紹Meta的視頻生成模型Emu Video&#xff0c;作為Meta發布的第二款視頻生成模型&#xff0c;在視頻生成領域發揮關鍵作用。 &#x1f33a;優質專欄回顧&am…

Debian 上安裝PHP

1、安裝軟件源拓展工具 apt -y install software-properties-common apt-transport-https lsb-release ca-certificates 2、添加 Ond?ej Sur 的 PHP PPA 源&#xff0c;需要按一次回車&#xff1a; add-apt-repository ppa:ondrej/php 3、更新軟件源緩存&#xff1a; apt-g…

office 2019 關閉word窗口后卡死未響應

最近關閉word文件總是出現卡死未響應的狀態&#xff0c;必須從任務管理器才能殺掉word 進程&#xff0c;然后重新打開word再保存&#xff0c;很是麻煩。&#xff08;#其他特征&#xff0c;在word中打字會特別變慢&#xff0c;敲擊鍵盤半秒才出現字符。&#xff09; office官網…