didSet gets called during init and leads to crash

As The Swift Programming Language: Redirect

The willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer, after the superclass initializer has been called. They aren't called while a class is setting its own properties, before the superclass initializer has been called.

Should the didSet be called on the code below?
(The code would trigger circular init and crash.)

import Combine

struct S {
    var id = 0
}

class C: ObservableObject {
    static let sharded = C()
    @Published var index = S() {    
        didSet {
            print("didset")
            print(C.sharded.index)
        }
    }

var dummy: Int

    init() {
        // index = S(id: 1)

        dummy = 2
        setIndex()
    }

    func setIndex() {
        index = S(id: 1)
        print("index = 1 ed")
    }
}

print(C.sharded)

didSet should be called as at that point you've already initialised all properties (that way or another). If you didn't there would be a compilation error on a setIndex call. Minimal example:

class C {
    var index: Int = 0 {
        didSet {
            print("didSet")
        }
    }

    init() {
        print("b4")
        setIndex()
        print("after")
    }

    func setIndex() {
        index = 0
    }
}

C()

prints:

b4
didSet
after

BTW, while not super obvious this is the way it works:

init() {
    index = 0 // didSet is not called here
    index = 0 // neither here
    { index = 0 }() // didSet is called here
    // ditto for a method call
}
1 Like