Swift 组合接收器在设置时调用一次?
Swift Combine sink called once at setup?
我正在设置 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([=11=]) }
viewModel.name = "Alex"
当您订阅已发布的 属性 时,您仍然会收到一个已发布的事件,该事件是 属性 的当前值。但是,通过使用 $name
您将附加到一个流,该流将向您发送订阅的当前值和每个后续值。
我正在设置 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([=11=]) }
viewModel.name = "Alex"
当您订阅已发布的 属性 时,您仍然会收到一个已发布的事件,该事件是 属性 的当前值。但是,通过使用 $name
您将附加到一个流,该流将向您发送订阅的当前值和每个后续值。