UserDefaults
问题
UserDefaults 的原理和限制是什么?
答案
基本用法
// 存
UserDefaults.standard.set("Alice", forKey: "username")
UserDefaults.standard.set(25, forKey: "age")
UserDefaults.standard.set(true, forKey: "isLoggedIn")
// 取
let name = UserDefaults.standard.string(forKey: "username") // Optional
let age = UserDefaults.standard.integer(forKey: "age") // 默认 0
let loggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")
// 删
UserDefaults.standard.removeObject(forKey: "username")
@AppStorage(SwiftUI)
struct SettingsView: View {
@AppStorage("theme") private var theme = "light"
var body: some View {
Picker("Theme", selection: $theme) {
Text("Light").tag("light")
Text("Dark").tag("dark")
}
}
}
原理与限制
- 底层是 plist 文件(
Library/Preferences/bundleid.plist) - 启动时全量加载到内存 → 大数据会影响启动速度
- 同步到磁盘有延迟(
synchronize()已无需手动调用) - 不适合存储大量数据、敏感信息
不要用 UserDefaults 存储敏感信息
UserDefaults 以明文 plist 存储在沙盒中。越狱设备或备份文件可以直接读取。密码、Token 等敏感信息应使用 Keychain。
常见面试问题
Q1: UserDefaults 是线程安全的吗?
答案:是的。Apple 文档说明 UserDefaults 是线程安全的,可以在多线程中读写。但频繁写入可能有性能问题。
Q2: UserDefaults 能存储自定义对象吗?
答案:需要对象遵循 Codable,先编码为 Data 再存储:
let user = User(name: "Alice", age: 25)
let data = try? JSONEncoder().encode(user)
UserDefaults.standard.set(data, forKey: "user")