简体   繁体   English

为什么在初始化程序中设置时调用 didSet?

[英]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:我在玩 SwiftUI,我有一个看起来像这样的类:

class Foo: ObservableObject {

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

    init() {
        self.foo = 1
    }
}

The didSet is always called. didSet 总是被调用。 According to Apple docs it should not be called.根据Apple 文档,不应调用它。 Is there something special going on with the @Published property wrapper? @Published属性包装器有什么特别之处吗?

All about types... Ok, let's consider code...所有关于类型......好吧,让我们考虑代码......

case 1: @Published var foo: Int情况 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!情况 2: @Published var foo: Int! (the same will be for @Published var foo: Int? ) @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.因此,IMO,答案是肯定的,这是@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.注意:如果在self.foo = 1行设置断点并使用 ^F7 (Control-Step Into) 执行两种情况下的指令,您可以在运行时看到所有图片......非常有趣的内部结构。

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

The rule is that setter observers are not called during initialization.规则是在初始化期间不调用 setter 观察者。 But by the time you set this property, initialization is over!但是当你设置这个属性时,初始化就结束了! The property was already given its initial value, namely nil .该属性已被赋予其初始值,即nil Therefore even though you are in an init method, you are not “during initialization” and the setter observer runs.因此,即使您在init方法中,您也不是“在初始化期间”并且 setter 观察者运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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