You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode Preview因Swift Data复杂关联模型崩溃问题排查求助

Core Data Preview容器添加多个Model3崩溃问题修复建议

问题描述

使用ModelContainer构建Core Data预览数据库时,添加多个Model3实例会在打印“Container Done”后崩溃,仅添加单个Model3时可正常运行。

相关代码

PreviewContainer代码

@MainActor
let previewContainer: ModelContainer = {
    do {
        let container = try ModelContainer(for: Model1.self, Model2.self, Model3.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))
        
        let cList = [ Model1(name: "Name1") ,Model1(name: "Name2") ,Model1(name: "Name3")]
            
        cList.forEach { c in
            container.mainContext.insert(c)
            c.childModel1 = [Model1(name: "Name1Child"),Model1(name: "Name2Child")]
        }
        
        let aList = [Model2(name: "Name1"),Model2(name: "Name2"),Model2(name: "Name3")]
            
        aList.forEach { a in
            container.mainContext.insert(a)
        }
        
        let tList = [ Model3(amount: Int.random(in: 0...2000000), Model3(amount: Int.random(in: 0...2000000) ]

            
        tList.forEach { t in
            container.mainContext.insert(t)
            t.model2 = aList[0]
            t.model1 = cList[0]
        }
        //try container.mainContext.save()//Trying the suggestion in the comments. It no longer prints ""
        print("Container Done")
        return container
    } catch {
        fatalError("Failed to create container")
    }
}()

Model3代码

@Model public class Model3 {
    private var amount: Int
    @Relationship(inverse: \Model1.model3) var model1: Model1?
    
    @Relationship(inverse: \Model2.model3) var model2: Model2?
    @Relationship var model2Old: Model2?
    
    init(amount: Int, model1: Model1? = nil, model2: Model2? = nil, model2Old: Model2? = nil) {
        self.amount = amount
        self.model1 = model1
        self.model2 = model2
        self.model2Old = model2Old
    }
}

崩溃日志

CrashReportError: PEM crashed due to an uncaught exception

PEM crashed due to an uncaught exception `NSInvalidArgumentException`. Reason: -[__NSDictionaryM UTF8String]: unrecognized selector sent to instance 0x600000234f20.

Process: PEM[8900]
Date/Time: 2024-04-21 13:54:10 +0000
Log File: <none>

修复与调试建议

  • 修复语法错误:tList数组初始化存在语法错误,第二个Model3实例后缺少闭合括号,正确写法应为:

    let tList = [ Model3(amount: Int.random(in: 0...2000000)), Model3(amount: Int.random(in: 0...2000000)) ]
    

    语法错误可能导致底层数据结构异常,触发后续崩溃。

  • 显式保存上下文:取消注释try container.mainContext.save()语句,确保所有插入的对象都被正确持久化到内存数据库中。预览环境对上下文状态的一致性要求较高,未保存的对象可能引发不可预期的错误。

  • 完善Relationship配置:Model3中的model2Old属性未设置反向关系(inverse),Core Data要求双向关系必须配置反向关联,否则会导致数据一致性问题。需要在Model2中添加对应的属性,并为model2Old设置反向关系:

    // 在Model2中添加对应属性
    @Relationship(inverse: \Model3.model2Old) var model2Old: Model3?
    
    // 在Model3中修改model2Old的注解
    @Relationship(inverse: \Model2.model2Old) var model2Old: Model2?
    
  • 调试对象状态:在插入Model3实例后、返回容器前添加断点,检查每个Model3实例的model1、model2属性是否正确指向已插入上下文的Model1/Model2对象,避免出现无效引用。

  • 简化测试用例:暂时注释掉model2Old等非必要属性,只保留amount、model1、model2,验证是否还会崩溃。若问题消失,再逐步恢复属性,定位具体引发崩溃的配置。

内容的提问来源于stack exchange,提问作者FeroX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:17:44