我如何处理我的 CoreData 实体的副本,它是一个 @ObservedObject或者我需要吗??

问题描述

就我而言,我有一个要更新的 ContactProfile 视图。我认为制作 Contact 实体的副本,编辑副本,然后将副本的属性“粘贴”回原始实体,然后将其保存在 managedobjectcontext 中是个好主意。

到目前为止,我所拥有的代码仅使 tempContact 成为对原始联系人的引用。这是有道理的,因为原始联系人是由 CoreData 生成的类,而不是结构。

解决这个问题的最佳方法是什么?还是我想太多了? @Observedobject 本身是否足以进行编辑,因为它不会保存到数据库中,直到在代码中稍后通过调用 private func saveContext() 函数显式调用它?

到目前为止,我有这个代码

    struct ContactProfile: View {
        
        @Environment(\.managedobjectContext) private var viewContext
        
        @FetchRequest(
            sortDescriptors: [NSSortDescriptor(keyPath: \Level.sortOrder,ascending: true)],animation: .default)
        
        private var levels: FetchedResults<Level>
        
        @Observedobject var contact: Contact
        
/// Old code
///        @State private var tempContact: Contact

///        init(contact: Contact){
///            _contact = Observedobject(initialValue: contact)
///            _tempContact = State(wrappedValue: contact)
///        }
   

///updated code below:
    
    @State private var tempContact = TempContact(firstName: "",lastName: "",birthDate: Date(),picture: nil)
        
    init(contact: Observedobject<Contact>) {
        _contact = contact
        _tempContact = State(initialValue: tempContact)
        tempContact.firstName = contact.wrappedValue.firstName ?? ""
        tempContact.lastName = contact.wrappedValue.lastName ?? ""
    }

     ///end of updated code


        var body: some View {
            Form {
                Text("@Observed: \(contact.firstName ?? "UnkNown") \(contact.lastName ?? "UnkNown")")
                Text("@State: \(tempContact.firstName ?? "UnkNown") \(tempContact.lastName ?? "UnkNown")")
                
                TextField("Enter name",text: Binding(
                    get: { self.tempContact.firstName ?? ""},set: { self.tempContact.firstName = $0 }
                )
                )
                
                [snipped the rest of the normal view code]
                

ContactProfile 是从 ContactsList 访问的,如下所示:


struct ContactsList: View {
    @Environment(\.managedobjectContext) private var viewContext
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Contact.lastName,animation: .default
    )
    
    private var contacts: FetchedResults<Contact>
    
    var body: some View {
        List {
            ForEach(contacts) { contact in
                NavigationLink(
                    destination: ContactProfile(contact: contact)) {
                    HStack (alignment: .firstTextBaseline) {
                        Text("\(contact.firstName ?? "UnkNown") \(contact.lastName ?? "UnkNown")")
                        Text("(\(contact.level?.name ?? ""))").font(.caption).foregroundColor(.gray)
                    }
                }
            }
            .onDelete(perform: deleteContacts)
        }
        .listStyle(PlainListStyle())
        .navigationTitle("Contacts")
        .navigationBarItems(trailing: Button(action: addContact) { Image(systemName: "plus") }
        )
    }
    
    [snip]
   

解决方法

处理 Core Data 中的更新很简单:

  1. 将您的 CoreData 托管对象传递到视图中。
  2. 设置变量以处理数据编辑输入并将它们设置为 CoreData 对象值的值,类似于您的结构,但在视图中为 @State。
  3. 验证输入后,将每个属性设置为其对应的@State 变量,如下所示: [您的实体名称].setValue([您的@State 变量],forKey: "[您的属性名称]").
  4. 将您的实体保存在托管对象上下文中,就像您创建该特定对象时一样。

这将更新您的对象,而不是创建一个新对象。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...