简体   繁体   中英

Why is didSet called when set inside an initializer?

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?

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.

在这里找到答案,当使用隐式解包变量时,它会离开初始化范围,因此 didSet 被称为: https ://stackoverflow.com/a/25231068/294661

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM