0

The didSet observer does not fire when the value is changed due to the assignment. Is this a bug or a feature?

struct ContentView: View {
    @StateObject var v = vm()
    var body: some View {
        Text(String(v.b))
            .padding()
    }
}

class vm: ObservableObject {
    @Published var b = false {
        didSet {
            print("hello didSet \(b)")
        }
    }
    
    let pub = CurrentValueSubject<Bool, Never>(false)
    
    init() {
        b = true
        pub.assign(to: &$b)
        pub.send(true)
        pub.send(false)
    }
}

Expected output:

hello didSet true

hello didSet false

hello didSet true

hello didSet false

Actual output:

hello didSet true

Assigning the value with .sink() is a workaround but why doesn't assign(to:) trigger the didSet observer?

Steve M
  • 9,296
  • 11
  • 49
  • 98
  • That's not the same question at all. – Steve M Jun 14 '21 at 13:33
  • 1
    Instead of assigning to published internal storage, assign by key path, like `pub.assign(to: \.b, on: self)` - it solves your case. But... in any case it brings cross-reference, so `sink` is preferable, because allows `weak self`. – Asperi Jun 14 '21 at 13:37

0 Answers0