Caches Directory — 是iOS应用程序沙箱中的一个目录,用于存储可以从网络恢复或重新加载的临时数据。根据Apple File System Basics (2024),系统可以随时删除Caches Directory中的文件以释放磁盘空间 — 应用程序必须正确处理这些文件的缺失并在必要时恢复它们。与Documents Directory不同,Caches中的数据不包含在iCloud和iTunes备份中,这减轻了用户的云存储负担。
要点
Caches Directory — 是iOS应用程序沙箱内的一个目录,经过优化用于存储可以在需要时恢复的数据。与Documents Directory不同,Caches不用于用户数据 — 它是用于加速应用程序运行的临时存储。
iOS使用Caches Directory来放置缓存的网络响应、预加载的图像、序列化对象以及应用程序可以恢复的数据。开发人员不应依赖于此目录中长期存储的数据。
根据Apple WWDC 2020的数据,约40%的iOS应用程序使用Caches Directory来存储缓存图像和网络数据,而25%的开发人员由于不理解这些目录之间的区别,错误地将应该放在Documents或Application Support中的数据放在了Caches中。
Caches的关键属性:应用程序必须正确处理缓存文件被系统删除的情况。如果删除缓存后应用程序的功能受到影响 — 意味着数据存储在了错误的目录中。
在Swift中,通过指定.cachesDirectory的标准FileManager方法获取Caches Directory的路径。这是一个简单的操作,几乎每个处理网络数据的iOS应用程序都会用到。
import Foundation
let fileManager = FileManager.default
guard let cachesURL = fileManager.urls(
for: .cachesDirectory,
in: .userDomainMask
).first else { return }
// 保存缓存的JSON
let cacheFile = cachesURL.appendingPathComponent("feed_cache.json")
let jsonData = try JSONSerialization.data(
withJSONObject: response,
options: [.prettyPrinted]
)
try jsonData.write(to: cacheFile)
Objective-C使用带有NSCachesDirectory的NSSearchPathForDirectoriesInDomains。尽管Apple推荐Swift API,但使用Caches Directory的Objective-C代码仍然可运行且受支持。
@import Foundation;
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSCachesDirectory,
NSUserDomainMask,
YES
);
NSString *cachesPath = paths.firstObject;
NSString *cacheFile = [cachesPath stringByAppendingPathComponent:@"feed_cache.plist"];
Swift项目应优先选择基于URL的API:它是类型安全的,并且可以更好地与SwiftUI和Combine等现代框架集成。
Caches Directory适用于应用程序用于加速运行的几类数据,但它不是唯一的事实来源。正确选择要缓存的数据直接影响UX和应用程序性能。
JSON响应来自API、新闻提要数据、对象列表 — 应用程序可以从服务器重新加载的所有内容。使用URLCache自动缓存HTTP响应,或手动保存序列化对象。
图像从网络下载 — Caches Directory最常见的用例。SDWebImage和Kingfisher等库默认将缓存的图像保存在Caches中。
| 数据类型 | 适用于Caches | 保存期限 |
|---|---|---|
| JSON API响应 | 是 | 直到系统清理 |
| 图像来自网络 | 是 | 直到系统清理 |
| 调试日志 | 有条件 | 最好放在tmp |
| 游戏存档 | 否 | 仅Documents |
| 应用程序配置 | 否 | Application Support |
如果数据无法恢复 — 它们的位置不在Caches中。这是最简单的标准:想象一下明天系统删除Caches中的所有文件。如果应用程序继续正常运行 — 数据存储正确。
iOS自动管理Caches Directory的清理,但确切的触发器和算法未被Apple记录。已知系统可以在磁盘空间不足时以及在使用Offload Unused Apps功能时删除Caches中的文件。
清理过程对应用程序是透明的:系统在不通知的情况下删除文件。应用程序必须在读取前检查文件是否存在,并在不存在时重新创建。不依赖长期存储 — 是使用Caches的关键要求。
根据Apple的“File System Basics”(2024)文章,应用程序不应期望Caches Directory中的文件在会话之间可用。建议开发人员实现fallback机制:当缓存文件不存在时 — 从网络下载数据并再次保存到Caches。
一个单独的场景 — 卸载应用程序(Offload)。当此功能激活时,iOS会删除应用程序但保留其Documents Directory。Caches Directory在此过程中被删除。恢复应用程序的用户不会获得缓存数据 — 应用程序必须重新下载它们。
Caches和Temporary(tmp)之间的区别经常让开发人员感到困惑。两个目录都存储临时数据,但具有不同的生命周期保证和目的。
| 特征 | Caches Directory | Temporary Directory |
|---|---|---|
| 生命周期 | 会话到会话(不保证) | 仅在会话内 |
| 系统清理 | 空间不足时 | 会话结束或重启时 |
| 目的 | 用于加速的缓存 | 非常临时的数据 |
| 示例 | 缓存的图像 | 导出前的临时文件 |
| 备份 | 否 | 否 |
如果数据在应用程序启动之间保存有用但可以恢复,请选择Caches。如果数据仅在当前会话中需要并且在应用程序结束后没有价值,请使用tmp。
使用Caches Directory需要遵守一些规则,这些规则有助于避免数据丢失、应用程序意外行为和性能问题。
每次从Caches读取前都应调用FileManager.fileExists(atPath:)。如果文件不存在 — 从原始源下载数据并保存到缓存。永远不要假设Caches中的文件存在。
设置应用程序中Caches Directory的最大大小。例如,图像为50 MB,JSON响应为10 MB。超过限制时,按修改日期删除最旧的文件。
import Foundation
func trimCache(to maxSizeBytes: Int) {
let cachesURL = FileManager.default
.urls(for: .cachesDirectory, in: .userDomainMask)
.first!
guard let enumerator = FileManager.default
.enumerator(
at: cachesURL,
includingPropertiesForKeys: [.fileSizeKey, .contentModificationDateKey]
)
else { return }
// 枚举并删除旧文件
// 当超过大小限制时
}
遵循这些实践可确保应用程序在系统的所有缓存清理操作中正常运行,并且用户不会遇到意外的数据丢失。
常见问题
不会,iOS在删除Caches中的文件前不会发送通知。清理过程对应用程序是完全透明的。了解删除的唯一方法 — 在尝试读取文件时FileManager返回nil或抛出错误,应用程序必须处理这种情况。
用户没有通过Files或iTunes直接访问Caches Directory的权限。但是,用户可以通过设置 > 通用 > 存储,选择特定应用程序并点击“卸载应用程序”来清理所有应用程序的缓存。iOS也可以在空间不足时自动清理缓存。
URLCache — 是Foundation中内置的HTTP请求缓存机制。它会自动保存和加载缓存的响应,底层使用Caches Directory。手动保存提供更多控制:可以选择格式、加密数据并单独管理每个文件的生命周期。
通过App Store更新应用程序时,Caches Directory会被保留。但是,如果新更新需要更多空间来安装,内容可能会被系统删除。开发人员不应依赖更新后Caches的保留 — 这是实现fallback机制的额外原因。
为特定的NSURLSession会话将URLCache设置为nil,或使用.reloadIgnoringLocalCacheData缓存策略。也可以使用空缓存创建URLSessionConfiguration配置:sessionConfiguration.urlCache = nil。这对于必须始终是最新的数据非常有用。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。