为什么Swift中CoreData NSManagedObject的绑定不能更新onChange?

fnvucqvd  于 2023-05-21  发布在  Swift
关注(0)|答案(1)|浏览(213)

上下文

我有一个非常简单的Form,使用MVVM架构。但是,我在这个实现中遇到了一个问题。我的DetailView有一个DummyState,它改变了EntityonChange的相应属性。

**问题:**一旦DetailView出现,Toggles都在,这是预期的。然而,当关闭本地Toggle时,另一个Toggle仍保持打开状态,这是意料之外的。然而,只要我与另一个元素(不在MRE中)交互,第二个Toggle似乎刷新并关闭。
编码

@objc(Entity) public class Entity: NSManagedObject {
    @NSManaged public var enabled: Bool
}

class FormViewModel: ObservableObject, CustomFormObservable {
    @Published var entity = Entity(context: ...)

    init() { self.entity.enabled = true }

    var isValid: Bool { self.entity.enabled }
}

struct FormView: View {
    @StateObject private var formVM = FormViewModel()

    var body: some View {
        CustomForm(formVM: formVM) {
            DetailView(entity: $formVM.entity)
        }
    }
}

struct DetailView: View {
    @Binding var entity: Entity
    @State private var localEnabled: Bool = true

    var body: some View {
        Toggle("Local Toggle", isOn: $localEnabled)
            .onChange(of: localEnabled) { entity.enabled = $0 }

        Toggle("Toggle", isOn: $entity.enabled)
    }
}

问题

  • 是什么导致了这种行为,我该如何解决它?
xtfmy6hx

xtfmy6hx1#

因为NSManagedObject是引用类型。
有一个简单的规则:

  • @State@Binding是用于像结构这样的值类型。
  • @StateObject@ObservedObject用于类等引用类型。

而且 * 美元符号引用 * 也只适用于值类型。
幸运的是,NSManagedObject默认符合ObservableObject

struct MainView: View {
    @StateObject private var formVM = FormViewModel()

    var body: some View {
        DetailView(entity: formVM.entity)
    }
}

struct DetailView: View {
    @ObservedObject var entity: Entity
    @State private var localEnabled: Bool = true

    var body: some View {
        Toggle("Local Toggle", isOn: $localEnabled)
            .onChange(of: localEnabled) { entity.enabled = $0 }

        Toggle("Toggle", isOn: $entity.enabled)
    }
}

相关问题