SwiftMidOpen-ended

Are `willSet` and `didSet` called when a property is set inside the initializer?

Explanation & Code

Answer: No — a type's own property observers are not called while its initializer sets the property; they only fire for assignments after initialization.

Code Example:

class Profile {
    var name: String {
        didSet { print("name changed to \(name)") }
    }

    init(name: String) {
        self.name = name      // ❌ didSet NOT called
    }
}

let p = Profile(name: "Mia") // prints nothing
p.name = "Lina"              // ✅ "name changed to Lina"

Subclass exception: When a subclass initializer sets a property inherited from its superclass, the superclass's observers are called — but only after super.init() has returned.

class Base {
    var value = 0 {
        didSet { print("Base.didSet: \(value)") }
    }
}

class Child: Base {
    override init() {
        super.init()
        value = 10   // ✅ "Base.didSet: 10"
    }
}

Workaround — force observers to run during init:

init(name: String) {
    defer { self.name = name } // runs after init's body, so didSet fires
    self.name = ""
}

This works but is easy to misread — prefer calling the side-effect explicitly from init instead.

Rate your understanding:

Ready to practice more Swift?

Test yourself with our interactive quiz mode or browse all curated questions for this topic.