【问题标题】:SwiftUI Core Data ObjectWillChange with a computed var in EntitySwiftUI Core Data ObjectWillChange 与实体中的计算变量
【发布时间】:2021-10-03 11:33:50
【问题描述】:

我有一个将 Person 和 MoneyEntries 实体存储在 Core Data DB 中的应用。

Person 与 MoneyEntry 有 1:many 关系。我在 Person 的扩展中创建了一个计算 var,它计算与此人相关的所有 MoneyEntry 条目的总和:

extension Person {
    var sumOfEntries: Double {
            var sum = 0.0
            entries.forEach({sum += $0.value})
            return sum
    }
}

在第一个视图中,我列出了所有 Person 对象及其对应的 MoneyEntries 的总和:

struct PeopleListView: View {
    @Environment(\.managedObjectContext) var viewContext

    @FetchRequest var people: FetchedResults<Person>

    init() {
        let request = NSFetchRequest<Person>(entityName: "Person")
        request.sortDescriptors = [NSSortDescriptor(key: "lastName_", ascending: true)]
        let predicate = NSPredicate(format: "TRUEPREDICATE")
        request.predicate = predicate
        _people = FetchRequest(fetchRequest: request)
    }

    var body: some View{
        ForEach(people, id: \.self) { person in
            Text("\(String(person.sumOfEntries) €")
        }
    }
}

在第二个视图中,我添加了一个 MoneyEntry 对象:

    let entryObj = MoneyEntry(context: viewContext)
    entryObj.person = person
    entryObj.value = valueAsDouble

    person.objectWillChange.send()
    
    try? viewContext.save()

但在我的第一个视图中,sumOfEntries 没有更新。我该怎么做才能解决这个问题?

【问题讨论】:

  • 计算属性不订阅任何内容,是否查看了核心数据派生属性?
  • @JoakimDanielson 我该怎么做?

标签: ios swift core-data swiftui


【解决方案1】:

好吧,在回答您最初的问题时,核心数据实体符合ObservableObject,因此您可以在计算属性中执行此操作:

extension Person {
    var sumOfEntries: Double {
            var sum = 0.0
            entries.forEach({sum += $0.value})
            objectWillChange.send() // Put it here
            return sum
    }
}

但是,你为什么要这样做?你可以简单地替换

var body: some View{
    ForEach(people, id: \.self) { person in
        Text("\(person.reduce(0) {$0.entries.value, +}.description €")
    }
}

为:

var body: some View{
    ForEach(people, id: \.self) { person in
        Text("\(String(person.sumOfEntries) €")
    }
}

并在现场计算。对于您引用的 Person 实体,它将始终是最新的,而无需求助于 objectWillChange 发布者。

【讨论】:

  • 您发布的替代版本不能这样工作。如果您的意思是 Text("(person.entries.reduce(0, {$0 + $1.value}))") 这并不能解决问题。条目实体接缝不更新。
  • 在 sumOfEntries 方法中调用objectWillChange.send() 也不能解决问题
  • 您必须发布更多代码。我拼凑了一个你想要的快速工作模型,它正在更新。您确实需要发布Minimal, Reproducible Example。我特别有兴趣看到你的PersistenceController,但你需要发布一个你在做什么的最小例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 2016-08-14
  • 1970-01-01
相关资源
最近更新 更多