SwiftData单元测试中直接使用ModelContext插入数据触发EXC_BREAKPOINT的原因
SwiftData单元测试中直接使用ModelContext插入数据触发EXC_BREAKPOINT的原因
这问题的根源其实是对象生命周期管理的问题,咱们一点点拆解看:
问题出在计算属性的特性 + 未持有容器实例
你定义的modelContainer是一个计算属性,每次访问它(比如modelContainer.mainContext或者container = modelContainer)都会重新执行一遍里面的代码,创建一个全新的ModelContainer实例。
看第一个不工作的方案:
在setUp里你只持有了modelContainer.mainContext,但生成这个context的ModelContainer本身并没有被测试类持有——setUp执行完后,这个临时创建的容器就被ARC自动回收销毁了。等到你在测试方法里调用context.insert(movie)时,这个context已经是一个“无家可归”的无效对象了,它依赖的容器早没了,自然就触发断点崩溃。
第二个方案为什么能工作?
而第二个方案里,你在测试类里加了private var container: ModelContainer!,并在setUp中把modelContainer赋值给它——这就相当于让测试类持有了这个容器实例,容器的生命周期和测试类的实例绑定,不会被提前回收。它的mainContext自然也能保持有效状态,后续的插入、查询操作也就都能正常执行了。
额外提个小优化
其实你还可以把modelContainer改成静态属性,避免每次访问都生成新容器(虽然是内存中的,开销不大,但更合理),比如:
// 改成静态属性,只初始化一次 static let modelContainer: ModelContainer = { do { return try ModelContainer(for: Movie.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true)) } catch { fatalError("Failed to create container.") } }()
这样不管访问多少次,都是同一个容器实例,也能避免一些潜在的生命周期问题。
备注:内容来源于stack exchange,提问作者Jintae
相关产品推荐
相关产品推荐

