设置关系时的 SwiftData EXC_BREAKPOINT

Ken*_*and 2 swift-data

我是第一次使用 SwiftData,当我尝试设置关系的值时遇到崩溃问题。

我有一个Profession代表游戏中工作的对象。每个人都Profession可能有开支(Expense如抵押贷款)。

我试图在应用程序首次启动时填充初始数据。当我创建第一个时Profession,我创建了一个Expense似乎可以工作的项目,但是当我创建第二个时,Expense应用程序Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1c3c6203c)在尝试设置Expense.profession关系时崩溃了。Xcode 扩展profession属性以显示 get/set,但它在 set 函数中崩溃。

我错过了一些明显的东西吗?或者 SwiftData 是否期望我做一些与 CoreData 在这种情况下非常不同的事情?

@Model
class Profession {
    var id: UUID
    var name: String
    
    @Relationship(deleteRule: .cascade, inverse: \Expense.profession) var expenses: [Expense] = []
        
    init(name: String) {
        self.id = UUID()
        self.name = name
    }
    
    convenience init(professiondefault: ProfessionDefault) {
        self.init(name: professiondefault.name)
        
        let taxes = Expense(name: "Taxes", cashflow: professiondefault.taxes, isPermanent: true, profession: self)
        
        // crashes on the next line
        let otherExpenses = Expense(name: "Other Expenses", cashflow: professiondefault.otherExpenses, isPermanent: true, profession: self)
        
    }
    
}


@Model
class Expense {
    let id: UUID
    var cashflow: Int
    let isPermanent: Bool
    var name: String
    
    var profession: Profession? 
    
    init(name: String, cashflow: Int, isPermanent: Bool, profession: Profession? = nil) {
        self.id = UUID()
        self.cashflow = cashflow
        self.isPermanent = isPermanent
        self.name = name
        self.profession = profession
    }
    
}
Run Code Online (Sandbox Code Playgroud)

Joa*_*son 9

我相信我已经找到了实现这项工作的模式。当同时创建两个相关对象时,您需要先将要分配的对象插入到模型上下文中,然后再连接这两个对象

所以这有效

let profession = Profession(name: "New profession")
modelContext.insert(profession) // <-- Insert first
let expense1 = Expense(name: "Expense 1", cashflow: 10, isPermanent: false)
let expense2 = Expense(name: "Expense 2", cashflow: 10, isPermanent: false)
profession.expenses.append(contentsOf: [expense1, expense2])

// this is also ok 
//  profession.expenses.append(expense1)
//  profession.expenses.append(expense2)

Run Code Online (Sandbox Code Playgroud)

如果我们想将一个职业分配给一项费用,则可以这样做:

let profession2 = Profession(name: "New profession")
let expense3 = Expense(name: "Expense 3", cashflow: 10, isPermanent: false)
let expense4 = Expense(name: "Expense 4", cashflow: 10, isPermanent: false)

modelContext.insert(expense3) // <-- Insert first
expense3.profession = profession2
modelContext.insert(expense4) // <-- Insert first
expense4.profession = profession2
Run Code Online (Sandbox Code Playgroud)