跳到主要内容

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")

相关链接