Swift Data操作模型数组时崩溃问题求助
Swift Data嵌套模型崩溃问题解决
问题根源分析
- 错误使用
@Relationship:Set类中的reps是基本数据类型(Int),@Relationship仅用于关联其他@Model类对象,不能用于基本类型,这是核心错误之一。 - 未将模型纳入Swift Data上下文管理:直接通过
Routine()实例化对象,没有将其添加到ModelContext中,嵌套的Exercise和Set也未被上下文追踪,导致访问关联数组时崩溃。
修正后的完整代码
1. 模型定义(修复@Relationship误用)
@Model class Routine { @Relationship var exercises: [Exercise] init() { self.exercises = [] } // 初始化时添加默认数据的方法,需在上下文环境中调用 func addDefaultExercise(context: ModelContext) { let set = Set(reps: 0) let exercise = Exercise(sets: [set]) context.insert(set) context.insert(exercise) self.exercises.append(exercise) } func getRep() -> Int { guard let firstExercise = exercises.first, let firstSet = firstExercise.sets.first else { return 0 } return firstSet.reps } func increase() { guard let firstExercise = exercises.first, let firstSet = firstExercise.sets.first else { return } firstSet.reps += 1 } } @Model class Exercise { @Relationship var sets: [Set] init(sets: [Set]) { self.sets = sets } } @Model class Set { // 移除@Relationship,直接用普通属性 var reps: Int init(reps: Int) { self.reps = reps } }
2. App入口(保持原有容器配置)
@main struct SwiftDataDemoApp: App { let container: ModelContainer init() { do { container = try ModelContainer(for: Routine.self, Exercise.self, Set.self) } catch { fatalError("Failed to create model container") } } var body: some Scene { WindowGroup { ContentView() } .modelContainer(container) } }
3. 视图部分(使用@Query或手动插入上下文管理模型)
struct ContentView: View { // 获取上下文 @Environment(\.modelContext) private var context // 使用@Query获取已存在的Routine,或初始化新对象 @Query private var routines: [Routine] var body: some View { VStack { Text("Reps: \(currentRoutine.getRep())") Button(action: { currentRoutine.increase() // 手动保存上下文(可选,Swift Data通常自动处理,但显式保存更稳妥) try? context.save() }) { Text("Increase!") } } .onAppear { // 如果没有现有Routine,创建并添加到上下文 if routines.isEmpty { let newRoutine = Routine() context.insert(newRoutine) newRoutine.addDefaultExercise(context: context) try? context.save() } } } // 获取当前使用的Routine private var currentRoutine: Routine { routines.first ?? Routine() } }
关键修正点说明
- 移除
Set类中reps的@Relationship标记,基本数据类型无需关联配置。 - 所有
@Model对象必须通过ModelContext.insert(_:)方法添加到上下文,确保Swift Data能够追踪和管理这些对象及其关联关系。 - 在视图中通过
@Environment(\.modelContext)获取上下文,使用@Query查询现有数据,避免直接实例化未被管理的模型对象。 - 添加安全判断(
guard let),防止数组为空时的越界访问,提升代码健壮性。
内容的提问来源于stack exchange,提问作者Tobilence
相关产品推荐
相关产品推荐

