我正在设置一个sink
:
name.publisher
.removeDuplicates()
.receive(on: RunLoop.main)
.sink { [weak self] config in
guard let self = self else { return }
// this closure gets called right away at setup even though the @Published property `name` was already setup and did not change
}.store(in: &subscribers)
属性在可观察对象中声明如下:
@Published var name:String = ""
所以,我显然在这里遗漏了一些东西。为什么即使name
没有改变,在设置时也要调用一次sink ?我可以通过使用dropFirst()
操作符来避免这种行为,但是,我想了解为什么闭包总是在设置后立即调用一次?
为什么?
这是一个使用debugPrint
的游乐场,向您展示您从name.publisher
中获得的内容:
import UIKit
import Combine
//Holds the score
class ViewModel : ObservableObject {
@Published var name = "0"
}
let viewModel = ViewModel()
debugPrint(viewModel.name.publisher)
得到的是
Combine.Publishers.Sequence<Swift.String, Swift.Never>(sequence: "0")
所以你得到一个序列发布者,它只有一个项目"0"。它将发布该值一次,然后序列结束。订阅者每次附加到该序列时,它将获得序列中的所有项目(只有一个)和结束。
这可能不是你想要的。
相反,我认为你想使用$name
来访问发布属性:
import UIKit
import Combine
//Holds the score
class ViewModel : ObservableObject {
@Published var name = "0"
}
let viewModel = ViewModel()
let subscription = viewModel.$name.sink { print($0) }
viewModel.name = "Alex"
当您订阅发布属性时,您仍然会得到一个发布事件,该事件是属性的当前值。但是,通过使用$name
,您将附加到一个流,该流将向您发送订阅的当前值和每个后续值。