SwiftUI数据持久化存储优化踩坑记录
最近在做一个任务管理应用时,遇到了SwiftUI数据持久化的严重性能问题。最初使用了简单的UserDefaults和Codable方案,结果在数据量超过1000条时,应用启动时间从2秒飙升到15秒。
问题复现步骤
// ❌ 错误做法 - 直接使用UserDefaults存储大量数据
struct Task: Codable {
var id = UUID()
var title: String
var isCompleted: Bool
}
class TaskManager: ObservableObject {
@Published var tasks: [Task] = []
func loadTasks() {
guard let data = UserDefaults.standard.data(forKey: "tasks"),
let tasks = try? JSONDecoder().decode([Task].self, from: data) else { return }
self.tasks = tasks
}
func saveTasks() {
if let data = try? JSONEncoder().encode(tasks) {
UserDefaults.standard.set(data, forKey: "tasks")
}
}
}
优化方案
经过调研,我采用了SQLite结合CoreData的方案,并使用SwiftUI的@FetchRequest来管理数据流。以下是核心实现:
// ✅ 正确做法 - 使用CoreData + SQLite
import CoreData
@main
struct TaskApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(
\.managedObjectContext, persistenceController.container.viewContext
)
}
}
}
// Task实体类
@objc(Task)
class Task: NSManagedObject {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Task> {
return NSFetchRequest<Task>(entityName: "Task")
}
@NSManaged public var title: String
@NSManaged public var isCompleted: Bool
@NSManaged public var createdAt: Date
}
// 使用@FetchRequest优化数据读取
struct ContentView: View {
@Environment(
\.managedObjectContext
) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Task.createdAt, ascending: false)],
animation: .default
) private var tasks: FetchedResults<Task>
var body: some View {
List(tasks, id: \Task.id) { task in
Text(task.title)
}
}
}
性能对比
- UserDefaults方案:启动时间15s,内存占用高
- CoreData方案:启动时间0.3s,内存稳定
关键优化点
- 使用NSManagedObject而非Codable结构体
- 合理设置fetch请求的sortDescriptors
- 避免在主线程进行大量数据序列化
- 利用@FetchRequest自动管理数据更新
这个坑踩得真是够呛,建议大家在处理大量数据时直接上CoreData,别再用UserDefaults了!

讨论