具有父模型和子模型的 RealmSwift @ObservedResults,不能在写入事务之外修改托管 RLMArray
RealmSwift @ObservedResults with parent and child models, cannot modify managed RLMArray outside of a write transaction
我正在尝试在 SwiftUI 列表中显示一些简单的 Realm 对象。每个对象还有相关的子对象。
我可以使用 @ObservedResults(Parent.self)
属性 包装器很好地显示父对象。简单地添加或删除父对象 to/from 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)
}
}
}
}
}
}
这是我的模型:
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
}
}
通过单击按钮 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)
}
}
我正在尝试在 SwiftUI 列表中显示一些简单的 Realm 对象。每个对象还有相关的子对象。
我可以使用 @ObservedResults(Parent.self)
属性 包装器很好地显示父对象。简单地添加或删除父对象 to/from 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)
}
}
}
}
}
}
这是我的模型:
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
}
}
通过单击按钮 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)
}
}