Search code examples
swiftcombine

Why does Combine assign crash when writing to an optional property?


This code crashes ("Unexpectedly found nil while unwrapping an Optional value")

import Combine

class Receiver {
    var value: Int!
    var cancellables = Set<AnyCancellable>([])
    
    init(_ p: AnyPublisher<Int,Never>) {
        p.assign(to: \.value, on: self).store(in: &cancellables)
    }
}

let receiver = Receiver(Just(5).eraseToAnyPublisher())

It does not crash if I use p.sink { self.value = $0 }.store(in: &cancellables) instead of the assign, and it does not crash if I do not use an optional for the value-property.

To me this looks like a bug in Swift's constructor code, but maybe I am overlooking something?


Solution

  • Definitely a bug in Combine, it’s accessing the value when assigning it. If you change it to be a regular Optional rather than an implicitly unwrapped one (change ! to ?) it’ll work fine. For the most part, you should avoid implicitly unwrapped Optionals except if they’re absolutely necessary for design constraints.