Why is didSet called when set inside an initializer?

computed property swift
swift didset
swift didset newvalue
swift didset not called
stored property swift
swift lazy computed property
swift willset change value
swift get set

I'm playing around with SwiftUI and I have a class that looks something like this:

class Foo: ObservableObject {

    @Published var foo: Int! { // Implicit unwrapped optional
        didSet {
            print("foo")
        }
    }

    init() {
        self.foo = 1
    }
}

The didSet is always called. According to Apple docs it should not be called. Is there something special going on with the @Published property wrapper?

The rule is that setter observers are not called during initialization. But by the time you set this property, initialization is over! The property was already given its initial value, namely nil. Therefore even though you are in an init method, you are not "during initialization" and the setter observer runs.

Why are the willSet and didSet property observers not called when a , Why are the willSet and didSet property observers not called when a property is set during initialization in Swift? https://developer.apple.com/library/prerelease� Probably to avoid recursion-into-explosion. Similar to Quora User answer. Similarly, in a UI paradigm it is essential to allow for a UI element to be initialized without triggering downstream effect.

All about types... Ok, let's consider code...

case 1: @Published var foo: Int

is actually

var foo: Int
var _foo: Published<Int>

so

init() {
    self.foo = 1 // << Initialization
}

case 2: @Published var foo: Int! (the same will be for @Published var foo: Int?)

is actually

var foo: Int!
var _foo: Published<Int?> // !! Not primitive - generics class, types differ

so

init() {
    self.foo = 1 // << Assignment of Int(1)
}

Thus, IMO, answer is yes, it is something special about @Published.

Note: You can see all picture in run-time if set breakpoint at self.foo = 1 line and using ^F7 (Control-Step Into) go by instruction for both cases... very interesting internals.

Properties — The Swift Programming Language (Swift 5.3), 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 are not called while a class is setting its own properties, before the superclass initializer has been called. willSet and didSet observers are not called when a property is first initialized. They are only called when the property’s value is set outside of an initialization context. This is a quite neat as it means e.g. the didSet property is a good choice of launch point for delegate callbacks & functions, for your own custom classes.

Found the answer here, when using implicit unwrapped variable it leaves the initialised scope therefor didSet is called: https://stackoverflow.com/a/25231068/294661

swift property observer not trigge…, willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer. "When you assign a default value to a stored property, or set its value within an initializer, the value of that property is set directly, without calling any property observers." 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 are not called while a class is setting its own properties, before the superclass initializer has been called.

Properties in Swift, In Swift there a two types of property observers: One is called before the new value is which is called after the assignment, is marked with the keyword didSet. initialize the value inside the init method; set a default value for the property. The Animal structure also defines a failable initializer with a single parameter called species. This initializer checks if the species value passed to the initializer is an empty string. If an empty string is found, an initialization failure is triggered. Otherwise, the species property’s value is set, and initialization succeeds:

Swift Property Observers — Coding Explorer Blog, For the didSet, we check if the current value (since this is the didSet) of our new name inside parenthesis after the willSet or didSet, somewhat similar In Swift, the property observers are NOT called during initialization or� If you use defer inside of an initializer , for updating any optional properties or further updating non-optional properties that you've already initialized and after you've called any super.init() methods, then your willSet, didSet, etc. will be called. I find this to be more convenient than implementing separate methods that you have to keep track of calling in the right places.

Property Observers didSet and willSet in Swift 4, One thing to note is that willSet and didSet will never get called on setting the initial value of the property. It will only get called whenever you� Understanding why this works is key to understanding value types. Mutating a struct variable is semantically the same as assigning a new value to it. When we mutate something deep inside the struct, it still means we are mutating the struct, so didSet still needs to get triggered.

Comments
  • Tested on Xcode 11.2.1 - didSet is not called during initialise in your code snapshot. As well as w/o @Published.
  • I've tested on Xcode 11.3 (11C29) - didSet is not called during initialize in your code snapshot (as @Asperi wrote)
  • Sorry I made a typo. Check updated code in question. @Asperi