SwiftUI数据持久化存储优化

NiceFire +0/-0 0 0 正常 2025-12-24T07:01:19 SwiftUI · CoreData · 持久化存储

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,内存稳定

关键优化点

  1. 使用NSManagedObject而非Codable结构体
  2. 合理设置fetch请求的sortDescriptors
  3. 避免在主线程进行大量数据序列化
  4. 利用@FetchRequest自动管理数据更新

这个坑踩得真是够呛,建议大家在处理大量数据时直接上CoreData,别再用UserDefaults了!

推广
广告位招租

讨论

0/2000