【发布时间】:2021-08-19 14:40:12
【问题描述】:
我正在使用Realm 文档Integration Guides -> SwiftUI & Combine 中给出的示例尝试新的Realm 10 包装器,我喜欢使用@ObservedResults 和@ObservedRealmObject 时添加和删除记录是多么简单.我不太明白的一件事是为什么在从Group 对象中删除项目时,它只会从Group 中删除项目,但不会删除Item 领域对象中的实际项目。请参阅下面的领域浏览器图像。
这是通过应用程序 UI 添加和删除四 (4) 个项目后 Realm Browser 显示的内容,您可以看到这四 (4) 个项目已从 Group 中删除,但所有四 (4) 个项目都保留在Item 对象。
有人可以解释为什么在调用.onDelete(perform: $group.items.remove) 时,项目不会从Item 对象中删除,而只是从Group 对象中删除?我怎样才能删除它们?
我试着像这样删除它们...
ItemsView.swift
.onDelete(perform: deleteItems)
func deleteItems(at offsets: IndexSet){
let realm = try? Realm()
try! realm?.write {
// 1. delete items
for item in list.items{
realm?.delete(item)
}
// 2. delete the list
realm?.delete(list)
}
}
但我收到以下错误:
线程 1:“只能从它所属的 Realm 中删除一个对象。”
同样,整个代码可以在Integration Guides - 不同步。
编辑:为 LocalOnlyContentView、ItemsView、Group 和 Item 模型添加了代码。
Item.swift
import Foundation
import RealmSwift
/// Random adjectives for more interesting demo item names
let randomAdjectives = [
"fluffy", "classy", "bumpy", "bizarre", "wiggly", "quick", "sudden",
"acoustic", "smiling", "dispensable", "foreign", "shaky", "purple", "keen",
"aberrant", "disastrous", "vague", "squealing", "ad hoc", "sweet"
]
/// Random noun for more interesting demo item names
let randomNouns = [
"floor", "monitor", "hair tie", "puddle", "hair brush", "bread",
"cinder block", "glass", "ring", "twister", "coasters", "fridge",
"toe ring", "bracelet", "cabinet", "nail file", "plate", "lace",
"cork", "mouse pad"
]
final class Item: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name = "\(randomAdjectives.randomElement()!) \(randomNouns.randomElement()!)"
@Persisted var isFavorite = false
@Persisted(originProperty: "items") var group: LinkingObjects<Group>
}
Group.swift
import Foundation
import RealmSwift
final class Group: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var items = RealmSwift.List<Item>()
}
ItemsView.swift
struct ItemsView: View {
@ObservedRealmObject var group: Group
var leadingBarButton: AnyView?
var body: some View {
NavigationView {
VStack {
// The list shows the items in the realm.
List {
ForEach(group.items) { item in
ItemRow(item: item)
}
.onDelete(perform: $group.items.remove)
.onMove(perform: $group.items.move)
}.listStyle(GroupedListStyle())
.navigationBarTitle("Items", displayMode: .large)
.navigationBarBackButtonHidden(true)
.navigationBarItems(
leading: self.leadingBarButton,
trailing: EditButton())
HStack {
Spacer()
Button(action: {
$group.items.append(Item())
}) { Image(systemName: "plus") }
}.padding()
}
}
}
}
LocalOnlyContentView.swift
struct LocalOnlyContentView: View {
@ObservedResults(Group.self) var groups
var body: some View {
if let group = groups.first {
AnyView(ItemsView(group: group))
} else {
AnyView(ProgressView().onAppear {
$groups.append(Group())
})
}
}
}
SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = LocalOnlyContentView()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
【问题讨论】:
-
我认为您的模型可能已关闭 - 如果您尝试匹配指南,Item 对象应该具有 group 属性。你能包括你的组和项目模型吗?
-
查看更新的代码。我还为 SceneDelegate、LocalOnlyContentView 和 ItemsView 添加了代码。请注意,我直接从我的项目中复制并粘贴了代码。谢谢杰!
-
RealmStudio 屏幕截图中的内容似乎与这些模型不匹配。 Item 类有一个 isFavorite 属性,它不在屏幕截图中的 Item 模型中。
-
糟糕——你是对的,我忽略了它。因此,在该镜头中,您有一个 Group,其包含不包含任何项目的项目的 List 属性。例如List 是指向项目的“指针”,因此如果您从 List 中删除项目,它仍然存在于 Realm 中,只是不在 List 中。如果您删除实际项目,它也会将其从列表中删除。所以这个
group.items.remove会将它从列表中删除,而不是从领域中删除。你问的是这个吗? -
对,正如我所提到的,从列表中删除项目,只是从列表中删除它们,它不会删除实际的项目。如果要删除实际项目,则需要从 Realm 中删除 item,而不是从列表中删除。