【问题标题】:SwiftUI App Shows Realm Changes but Not New ObjectsSwiftUI 应用程序显示领域变化但不是新对象
【发布时间】:2023-09-29 01:23:01
【问题描述】:

Realm 10.7.3、Xcode 12.4、macOS 11.2.3

我正在试验 Realm 和 Combine+SwiftUI。当我在 Realm Studio 中更改我的数据时,它们会立即按预期反映在我的应用程序的 UI 中。但是当我添加删除一个对象时,我的应用 UI 并没有改变。

这是我的模型定义:

//--- Model ---
class Item: Object, ObjectKeyIdentifiable {
  @objc dynamic var _id = ObjectId.generate()
  @objc dynamic var text = ""
}

这是我的视图模型:

//--- View Model ---
class ItemModel: ObservableObject {
  static let shared = ItemModel()
  var token: NotificationToken? = nil
  @Published var items = [Item]()
  
  init(){
    let realm = try! Realm()
    let results = realm.objects(Item.self)
    items = Array(results)
   
    token = results.observe { [weak self] _ in
      print("-- updated --")
      self?.objectWillChange.send()
    }
  }
  
  deinit{
    token?.invalidate()
  }
}

最后,这是我的 SwiftUI 视图:

//--- View ---
struct ItemView: View {
  @StateObject private var model = ItemModel.shared

  var body: some View {
    ScrollView{
      VStack(spacing: 7){
        ForEach(model.items, id: \._id) { item in
          Text(item.text)
        }
      }
    }
  }
}

任何想法为什么我的应用程序不会显示新/删除的对象而只显示编辑?如果我重建我的应用程序,则会显示新/删除的对象。

【问题讨论】:

    标签: swiftui realm combine


    【解决方案1】:

    Realm Results 对象是实时更新对象,并且始终反映 Realm 中这些对象的当前状态。

    但是,如果您将 Realm Results 对象转换为数组

    items = Array(results)
    

    它将那些对象(结果)从 Realm 中“断开”,并且它(它们)不再实时更新。

    此外,Realm Results 对象是延迟加载的,这意味着它们仅在需要时才加载到内存中,因此数千个对象几乎不占用空间。

    将它们存储在数组中会改变 - 它们全部加载到内存中,可能会压倒设备。

    最佳实践是在使用 Realm 集合(结果、列表)的整个过程中将其保留为该类型的对象,而不是强制转换为数组。

    【讨论】:

    • 嗯,这比我预期的要简单得多。 ?感谢您的帮助!
    • 对象延迟加载是有道理的。我不确定是否可以将 Realm Results 对象设置为 @Published,所以我从一个数组开始。
    • @CliftonLabrum 这是一个常见问题。尽可能保持结果和列表的纯净。 .map 或 swift .filter 等很诱人,但是一旦您将这些 Swifty 函数应用到 Collection 中,它就不再是 Collection。因此,以 Realm 方式做事将减少未来的问题并保持您的代码更清洁。