Reputation: 16141
I want to achieve this: A class A
, which has a property var c1: C
and var b1: B
, if the property of C
changes, then the property of b1
should be updated.
Here is my code:
import UIKit
import Combine
struct B {
var b = "b"
}
class C: ObservableObject {
@Published var c: String = "c1"
}
class A: ObservableObject {
var b1 = B()
var cancellables = Set<AnyCancellable>()
@Published var c1 = C()
init() {
$c1.sink {
print("new value is \($0.c)") //Only print once
self.b1.b = $0.c
}.store(in: &cancellables)
}
func printMe() {
print("b1.b: \(b1.b)")
print("c1.c: \(c1.c)")
}
}
let a = A()
a.c1.c = "c2"
a.printMe()
a.c1.c = "c3"
a.printMe()
The output is:
new value is c1
b1.b: c1
c1.c: c2
b1.b: c1
c1.c: c3
Every time the a.c1.c
was updated I expected a.b1.b
should be updated automatically by sink
, not sure if anything I missed, the sink
closure body just was called once.
Any suggestion? thanks!
Upvotes: 0
Views: 3411
Reputation: 119242
With @Published var c1 = C()
and $c1.sink
you are observing changes to A
's property c1
. This assignment does not change, since it is a reference type, so the sink is only called on initialisation.
Updating the sink to:
c1.$c.sink {
print("new value is \($0)") //Prints every time!
self.b1.b = $0
}.store(in: &cancellables)
Gives the behaviour you're looking for. I don't think the c1 publisher will emit any values in this scenario, but it's not clear what behaviour you're looking for there so I haven't gone into it.
Upvotes: 2