nrj*_*nrj 5 realm swift swiftui
我正在尝试在 SwiftUI 列表中显示一些简单的 Realm 对象。每个对象还有相关的子对象。
我可以通过使用@ObservedResults(Parent.self)
属性包装器来很好地显示父对象。只需向 Realm 添加或删除父对象即可更新列表,这非常有效。
当我想显示相关的子模型时,就会出现问题。当我尝试以与添加父模型相同的方式在 Realm 中添加子模型时,也使用默认的 Realm.Configuration,我得到RLMException
一句话Cannot modify managed RLMArray outside of a write transaction.
这是一个简单的 SwiftUI 视图,说明了该问题。
struct ContentView: View {
@ObservedResults(Parent.self) var parents
var body: some View {
VStack(spacing: 15) {
Button("Create parents") {
let realm = try! Realm()
try! realm.write {
realm.add(Parent(id: 1, name: "Nick"), update: .all)
realm.add(Parent(id: 2, name: "Lucas"), update: .all)
realm.add(Parent(id: 3, name: "Ryan"), update: .all)
}
}
Button("Create child") {
guard let parent = parents.first else {
return
}
let realm = try! Realm()
try! realm.write {
let child = Child(id: parent.children.count + 1, name: "Foo")
parent.children.append(child)
}
}
Button("Delete all") {
let realm = try! Realm()
try! realm.write {
realm.deleteAll()
}
}
List(parents) { parent in
VStack {
Text(parent.name)
ForEach(parent.children){ child in
Text("Child: \(child.name)")
.padding(.leading, 10)
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的模型:
class Parent: Object, ObjectKeyIdentifiable {
@objc dynamic var id: Int = 0
@objc dynamic var name: String = ""
var children = List<Child>()
override class func primaryKey() -> String? {
return "id"
}
convenience init(id: Int, name: String) {
self.init()
self.id = id
self.name = name
}
}
class Child: Object, ObjectKeyIdentifiable {
@objc dynamic var id: Int = 0
@objc dynamic var name: String = ""
private let parents = LinkingObjects(fromType: Parent.self, property: "children")
override class func primaryKey() -> String? {
return "id"
}
convenience init(id: Int, name: String) {
self.init()
self.id = id
self.name = name
}
}
Run Code Online (Sandbox Code Playgroud)
通过单击按钮Create parents
,Delete all
您会看到父模型按预期出现和消失。单击Create child
会产生错误。
我在这里真的很茫然,非常感谢任何帮助。谢谢!
回答我自己的问题。看来您必须先访问thaw
父模型(无论这意味着什么),然后才能将任何子模型附加到它。我在任何地方的文档中都找不到提到的内容,因此这可能是一个错误。
无论如何,这是修复方法:
Button("Create child") {
guard let parent = parents.first?.thaw() else {
return
}
let realm = try! Realm()
try! realm.write {
let child = Child(id: parent.children.count + 1, name: "Foo")
parent.children.append(child)
}
}
Run Code Online (Sandbox Code Playgroud)