1

My code is as follows。The name in the data is not changed,but hasChanges always returned true ,Did I do something wrong? Thank you very much for your help !

struct SwiftUI: View {
  @Environment(\.managedObjectContext) var moc
  @Environment(\.presentationMode) var pre: Binding<PresentationMode>
  var data: CoreData
  @State private var name = ""

  var body: some View {
    NavigationView {
      HStack {
        TextField("name", text: self.$name)
      }.onAppear{
        self.name = self.data.name ?? ""
      }

      Button(action: dataSave) {
        HStack {
          Text("Done")
        }
      }
    }
  }
  func dataSave() {
    self.data.name = self.name
    if moc.hasChanges {
      do {
        try moc.save()
        self.pre.wrappedValue.dismiss()
      } catch { print(error.localizedDescription) }
    } else {
      self.pre.wrappedValue.dismiss()
    }
  }
}

Why is it always returned true here?

moc.hasChanges
Soyl
  • 13
  • 2

1 Answers1

1

NSManagedObjectContext.hasChanges is set to true when you assign to any attribute of an object in that context, even if the attribute's value is the same as it had before.

You can change your code to do:

    if self.name != self.data.name {
        self.data.name = self.name
    }
    if moc.hasChanges { /* ... */ }

or, check hasPersistentChangedValues on the object itself (not the context):

    self.data.name = self.name
    if self.data.hasPersistentChangedValues {
      do {
        try moc.save()
        self.pre.wrappedValue.dismiss()
      } catch { print(error.localizedDescription) }
    } else {
      self.pre.wrappedValue.dismiss()
    }
  }

Unfortunately NSManagedObjectContext does not have an equivalent hasPersistentChangedValues property. The second approach is only reasonable in your example and not the general case, where there could be many objects in the context that may have changed.

For more information on the behavior of hasChanges and hasPersistentChangedValues see this answer: NSManagedObject's hasChanges is true while changedValues is empty

Steve
  • 86
  • 1
  • 5