I would like to update some variables with values received when handling a newly published value. For example, given:
class ProductViewModel: ObservableObject {
@Published var PublishedX: Int = 0
@Published var PublishedY: Int = 0
@Published var PublishedProduct: Int = 0
// ...
init() {
productPublisher = Publishers.CombineLatest(external.XPublisher, internal.YPublisher)
// .assignAndContinue(\.PublishedX, \.PublishedY) // something like this
.flatMap(MyPublishers.secretMultiplication)
.assign(to: \.PublishedProduct, on: self)
}
}
I would like to also assign the new values of XPublisher and YPublisher to variables (PublishedX and PublishedY respectively).
Is there a way to set these two variables and then continue handling the event?
If your deployment target is a 2020 system (like iOS 14+ or macOS 11+), you can use a different version of the assign
operator to avoid retain cycles and to avoid storing cancellables:
init() {
external.XPublisher.assign(to: $PublishedX)
external.YPublisher.assign(to: $PublishedY)
external.XPublisher
.combineLatest(external.YPublisher) { $0 * $1 }
.assign(to: $PublishedProduct)
}
There is no built-in variant of assign(to:on:)
that returns another Publisher
instead of a Cancellable
.
Just use multiple assign
s:
class ProductViewModel: ObservableObject {
@Published var PublishedX: Int = 0
@Published var PublishedY: Int = 0
@Published var PublishedProduct: Int = 0
init() {
external.XPublisher
.assign(to: \.PublishedX, on: self)
.store(in: &tickets)
internal.YPublisher
.assign(to: \.PublishedY, on: self)
.store(in: &tickets)
external.XPublisher
.combineLatest(internal.YPublisher) { $0 * $1 }
.assign(to: \.PublishedProduct, on: self)
.store(in: &tickets)
}
private var tickets: [AnyCancellable] = []
}
Note that these subscriptions create retain cycles. Swift will not be able to destroy an instance of ProductViewModel
until the tickets
array is cleared. (This is not a property of my suggestion. Your original code also needs to store its subscription somewhere, else it will be cancelled immediately.)
Also, the existence of PublishedProduct
is questionable. Why not just a computed property?
var product: Int { PublishedX * PublishedY }
You may want to check out this library
From their ReadMe :
var label1: UILabel
var label2: UILabel
var text: UITextField
["hey", "there", "friend"]
.publisher
.assign(to: \.text, on: label1,
and: \.text, on: label2,
and: \.text, on: text)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.