Core Data Earthquakes Demo预览时崩溃问题求助
Core Data Earthquakes Demo 预览崩溃问题
我正在学习Core Data,测试苹果官方的「Earthquakes - Loading and Display a large Data Feed」Demo时遇到了Canvas预览崩溃的问题:只要使用Quake.preview,编辑器就会崩溃。尝试查看崩溃日志但无法定位原因,将ContentView中的provider从.preview改为.shared后就不会崩溃。请问有人知道原因吗?
相关代码:
ContentView PreviewProvider代码
struct ContentView_Previews: PreviewProvider { static let quakesProvider = QuakesProvider.preview static var previews: some View { ContentView(quakesProvider: quakesProvider) .environment(\.managedObjectContext, quakesProvider.container.viewContext) } }
Quake 预览相关代码
/// An earthquake for use with canvas previews. static var preview: Quake { let quakes = Quake.makePreviews(count: 1) return quakes[0] } static func makePreviews(count: Int) -> [Quake] { var quakes: [Quake] = [] let viewContext = QuakesProvider.preview.container.viewContext for index in 0..<count { let quake = Quake(context: viewContext) quake.code = UUID().uuidString quake.time = Date().addingTimeInterval(Double(index) * -300) quake.magnitude = .random(in: -1.1...10.0) quake.place = "15km SSW of Cupertino, CA" quakes.append(quake) } return quakes }
QuakesProvider 预览代码
/// A quakes provider for use with canvas previews. static let preview: QuakesProvider = { let provider = QuakesProvider(inMemory: true) Quake.makePreviews(count: 10) return provider }()
问题原因与解决方法
问题出在循环依赖和上下文初始化顺序冲突:
QuakesProvider.preview的初始化闭包里调用了Quake.makePreviews(count:10),而makePreviews又会直接访问QuakesProvider.preview.container.viewContext——此时QuakesProvider.preview还在初始化过程中,Core Data上下文尚未完全创建就被调用,直接触发了编辑器崩溃。- 换成
.shared不会崩溃,是因为.shared的初始化逻辑没有这种循环依赖,上下文是完全初始化完成后才被使用的。
修复方案:
- 修改
QuakesProvider.preview,把测试数据创建逻辑放在初始化内部,避免外部调用带来的循环依赖:
static let preview: QuakesProvider = { let provider = QuakesProvider(inMemory: true) let viewContext = provider.container.viewContext for index in 0..<10 { let quake = Quake(context: viewContext) quake.code = UUID().uuidString quake.time = Date().addingTimeInterval(Double(index) * -300) quake.magnitude = .random(in: -1.1...10.0) quake.place = "15km SSW of Cupertino, CA" } return provider }()
- 调整
Quake的预览方法,让它接收外部传入的上下文,不再直接依赖QuakesProvider.preview:
static func makePreviews(count: Int, context: NSManagedObjectContext) -> [Quake] { var quakes: [Quake] = [] for index in 0..<count { let quake = Quake(context: context) quake.code = UUID().uuidString quake.time = Date().addingTimeInterval(Double(index) * -300) quake.magnitude = .random(in: -1.1...10.0) quake.place = "15km SSW of Cupertino, CA" quakes.append(quake) } return quakes } static var preview: Quake { let provider = QuakesProvider.preview let quakes = Quake.makePreviews(count: 1, context: provider.container.viewContext) return quakes[0] }
这样就能打破循环依赖,确保Core Data上下文完全初始化后再被使用,Canvas预览就不会崩溃了。
内容的提问来源于stack exchange,提问作者Noem
相关产品推荐
相关产品推荐

