gpt4 book ai didi

swiftui - Combine 是否有仅在值实际更改时才发布的发布者?

转载 作者:行者123 更新时间:2023-12-05 00:44:47 34 4
gpt4 key购买 nike

有没有办法让 @Published 变量只在新值与旧值不同时才发布其值?

现在如果我们有

@Published var test: Bool = false

我们做到了

test = false
test = false
test = false

发布者被调用了 3 次。这很烦人,因为它有时会导致我的 SwiftUI View 被重新创建,因为在层次结构中较高的某个位置,发布者被设置为之前设置的值,通过另一个被触发的发布者(并且这会破坏文本字段输入,因为 View 模型通过发生这种情况时会重新创建层次结构)。

有没有办法只在从 false 变为 true 或反之亦然时发布?

一个示例场景:

我们在我们的应用程序中创建了一个用户对象,并且我们想向用户添加一辆车。如果没有找到汽车,应用程序应立即显示“添加汽车” View ,否则显示主应用程序 View 。为此,我们在某个地方有一个听众。在我们的顶层 View 中,我们有:


@ObservedObject var viewModel = UserViewModel()


var body: some View {
if !viewModel.hasVehicles {
return AnyView(AddVehicleView(viewModel:AddVehicleViewModel())
} else {
return AnyView(UserMainView(user: user))
}
}
}

在我们的 UserViewModel 我们有

class UserViewModel: ObservableObject {
@Published var hasVehicles: Bool = false

  • 一些代码会在某些监听器触发时更新该 bool 值。

AddVehicleView 中,我们有一个表单,允许用户填写一些文本字段并保存车辆。

现在想象一下,由于某种原因,更新 hasVehicles 属性的代码被触发,但仍然没有车辆。会发生什么:

hasVehicles = false

并且顶层 View 被重新评估,导致 return AnyView(AddVehicleView(viewModel:AddVehicleViewModel()) 被执行,并且我的带有文本字段的表单被清空。

我想在这种情况下,我可以通过将 AddVehicleViewModel() 作为属性放在 View 结构中来解决它,但是在这种情况下不会解决它我们希望它被执行多次,因为这意味着下次构建 View 时,它将显示我们上次创建该 View 时的数据,因为我们重用了 View 模型。

最佳答案

在更新属性的代码中使用 Combine 的 removeDuplicates() 运算符。例如, View 模型可以创建一个发布者,该发布者根据其他两个 bool 属性的值更新一个 bool 属性:

    @Published var hasTrucks: Bool
@Published var hasCars: Bool
@Published var hasVehicles: Bool

func createVehiclePublisher() {
Publishers.CombineLatest($hasTrucks, $hasCars)
.map { $0 || $1 }
.removeDuplicates()
.assign(to: &$hasVehicles)
}

使用 removeDuplicates() 会导致 hasVehicles 仅在其值发生变化时更新。

关于swiftui - Combine 是否有仅在值实际更改时才发布的发布者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65905731/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com