带有 Core Data 的 SwiftUI:直接绑定到 NSManagedObject 与使用 @State 进行表单编辑

问题描述 投票:0回答:1

我正在使用 SwiftUI 和 Core Data 构建一个财务跟踪应用程序。在我的应用程序中,我有一个交易列表视图,用户可以在其中选择现有交易进行编辑。对于编辑视图,我对于选择这两种方法中的哪一种以及哪一种被认为是 Core Data SwiftUI 应用程序的“更好的实践”感到有点两难。

  1. 直接绑定到子上下文中的
    NSManagedObject

表单字段直接绑定到 NSManagedObject 的属性,并且子上下文用于隔离保存和放弃更改的能力。可能看起来像这样:

struct EditTransactionView: View {
    @ObservedObject var transaction: Transaction
    var childContext: NSManagedObjectContext

    init(transaction: Transaction, context: NSManagedObjectContext) {
        self.transaction = transaction
        self.childContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        self.childContext.parent = context
    }

    var body: some View {
        Form {
            TextField("Amount", text: $transaction.amount)
            DatePicker("Date", selection: $transaction.date)
            TextField("Notes", text: $transaction.notes)
        }
        .navigationBarItems(trailing: Button("Save") {
            if self.childContext.hasChanges {
                try? self.childContext.save()
            }
        })
    }
}
  1. 使用
    @State
    属性:

通过这种方法,我可以使用 NSManagedObject 的数据初始化 @State 属性。当用户完成字段更新后,将手动更新 NSManagedObject。像这样的东西:

struct EditTransactionView: View {
    var transaction: Transaction
    @Environment(\.managedObjectContext) var moc

    @State private var amount: String
    @State private var date: Date
    @State private var notes: String

    init(transaction: Transaction) {
        _amount = State(initialValue: transaction.amount)
        _date = State(initialValue: transaction.date)
        _notes = State(initialValue: transaction.notes)
    }

    var body: some View {
        Form {
            TextField("Amount", text: $amount)
            DatePicker("Date", selection: $date)
            TextField("Notes", text: $notes)
        }
        .navigationBarItems(trailing: Button("Save") {
            transaction.amount = self.amount
            transaction.date = self.date
            transaction.notes = self.notes
            try? self.moc.save()
        })
    }
}

注意:示例过于简化,并未在实际实现中使用。

swift swiftui core-data
1个回答
0
投票

这些都不理想。第一个每次 View 结构初始化时都会初始化一个新的上下文对象,这本质上是内存泄漏。第二个初始化一个具有依赖值的状态,这意味着它不是事实的来源。

为了解决这些问题,请创建一个状态结构,在父视图中的操作中创建子上下文和子对象一次,然后传递到详细信息中。

© www.soinside.com 2019 - 2024. All rights reserved.