Dav*_*ing 6 swift swift-data swiftui
我有以下代码:
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
var schoolClass: SchoolClass
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Button("add", action: {
let schoolClassSubject = SchoolClassSubject(schoolClass: schoolClass)
schoolClass.schoolClassSubjects.append(schoolClassSubject)
})
}
.padding()
}
}
@Model
class SchoolClass {
var name: String
var schoolClassSubjects: [SchoolClassSubject] = []
init(name: String) {
self.name = name
}
}
@Model
class SchoolClassSubject {
var schoolClass: SchoolClass
init(schoolClass: SchoolClass) {
print("test")
self.schoolClass = schoolClass
}
}
Run Code Online (Sandbox Code Playgroud)
schoolClass已保存在 swiftData 中并作为属性传递给ContentView.
换行符let schoolClassSubject = SchoolClassSubject(schoolClass: schoolClass)有以下例外情况:
*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“非法尝试在不同上下文中的对象之间建立关系“schoolClass”(源= <NSManagedObject:0x60000214cc30>(实体:SchoolClassSubject;id:0x60000024ebe0 x-coredata: ///SchoolClassSubject/t186670BB-357C-400C-8D6F-178BEB8F4B473; data: { schoolClass = nil; }) , 目的地 = <NSManagedObject: 0x60000214cd70> (实体: SchoolClass; id: 0x600000276740 x-coredata:///SchoolClass/t186670 BB -357C-400C-8D6F-178BEB8F4B472; data: { name = test; schoolClassSubjects = ( ); }))' *** 第一次抛出调用
如果我将我的模型更改为:
@Model
class SchoolClassSubject {
var schoolClass: SchoolClass? = nil
init() {
}
}
Run Code Online (Sandbox Code Playgroud)
我的保存代码如下:
let schoolClassSubject = SchoolClassSubject()
modelContext.insert(schoolClassSubject)
schoolClassSubject.schoolClass = schoolClass
schoolClass.schoolClassSubjects.append(schoolClassSubject)
Run Code Online (Sandbox Code Playgroud)
但我不想让它成为schoolClass可选schoolClassSubject的,因为它不是现实的。我怎样才能使它不可选并且仍然保存它而不出现给定的错误?
这个答案是使用 Xcode 15.0 beta 2 编写的,在未来的版本中我认为这个答案将变得无关紧要,我们可以更轻松地处理这个问题
再次强调,您必须使用@Relationship注释才能使关系正常工作,一旦您有了注释,SwiftData 就会为您处理它们。
因此,您不应在init模型的任何方法中包含任何关系属性。
所以将 init 更改SchoolClassSubject为
init() {}
Run Code Online (Sandbox Code Playgroud)
(我不知道这是否是一个错误,我们需要一个空的初始化,或者这只是一个奇怪的情况,因为没有其他属性)
然后将按钮操作中的代码更改为
let schoolClassSubject = SchoolClassSubject()
modelContext.insert(schoolClassSubject)
schoolClassSubject.schoolClass = schoolClass
Run Code Online (Sandbox Code Playgroud)
为了澄清上面的代码:
| 归档时间: |
|
| 查看次数: |
1460 次 |
| 最近记录: |