Swift 结合流水线比较草案模型

Swift Combine Pipeline to compare draft model

我在 Swift 中有一个 VielModelUI 处理我的个人模型。为了能够在视图中的编辑器中存储草图人员,我有两个对象:

@Published var person: Person
@Published var draftPerson: Person

在 UI 中,我只更改 draftPersons,直到用户单击“保存”,这会将 draftPerson 存储为人物。在编辑器的onAppear方法中,我将draftPerson重新设置为person

现在我想禁用编辑器的“保存”按钮,因此在 VM 中引入了一个布尔值“已修改”。使用管道,如果 draftPerson 不等于 person,我想将 modified 设置为 true,方法如下:

    $draftPerson.map { draftPerson in
        return draftPerson != self.person
    }
    .assign(to: \.modified, on: self)
    .store(in: &cancellables)

乍一看似乎可以正常工作,但如果我在文本字段中更改某些内容,修改后的值只会在该字段中进行第二次更改后才设置为 true。反之亦然,如果我删除键入的值,它只会在我删除一个原来存在的字符后设置回 false。

问题一: 是否有另一种“最佳实践”来处理草稿对象的更改并停用 Swift 中的“保存”按钮UI?

问题二: 为什么流水线“落后一改”?

非常感谢您的意见。

编辑:我创建了一个单独的应用程序部分,只关注管道,并意识到如果我删除其他管道,它确实可以按预期工作。我现在必须详细检查一下。不过,我会坚持我的第一个问题: 有什么我可以做得更好的吗?

请查找代码here on Github

你可以再声明一个@Published 属性然后把两个person和draftPerson的publishers合并起来发布是否相同,像这样:

@Published var person: Person
@Published var draftPerson: Person
@Published var saveDisabled: Bool = true

public init() {
    
    // all init code
    
    Publishers.CombineLatest($person, $draftPerson)
        .map { [=10=] ==  }
        .assign(to: &$saveDisabled)
    
}

但本质上不需要它,计算的 属性 将完成相同的工作:

var saveDisabled: Bool {
    person == draftPerson
}

因为 person 和 draftPerson 都被标记为 @Published 每次其中一个更改时 View 将收到更改通知,因此它也会选择 saveDisabled 的新值。