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

时间:2019-12-22 22:47:39

标签: swift swiftui

我正在玩SwiftUI,我有一个看起来像这样的类:

class Foo: ObservableObject {

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

    init() {
        self.foo = 1
    }
}

didSet总是被调用。根据{{​​3}},不应调用它。 @Published属性包装程序有什么特别之处吗?

3 个答案:

答案 0 :(得分:1)

所有关于类型的...好吧,让我们考虑一下代码...

情况1: @Published var foo: Int

实际上是

var foo: Int
var _foo: Published<Int>

如此

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

情况2:@Published var foo: Int!@Published var foo: Int?也是如此)

实际上是

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

如此

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

因此,IMO,答案是肯定的,这与@Published有关。

注意:如果在两种情况下都在指令self.foo = 1处设置断点并使用^ F7(Control-Step Into)指令,则可以在运行时查看所有图片...非常有趣的内部原理。

答案 1 :(得分:0)

在这里找到答案,当使用隐式未包装的变量时,它将初始化的范围留给didSet被称为:https://stackoverflow.com/a/25231068/294661

答案 2 :(得分:0)

规则是初始化期间不调用setter观察器。但是,当您设置此属性时,初始化已结束!该属性已被赋予其 initial 值,即nil。因此,即使您使用的是init方法,也不会在“初始化期间”运行setter观察程序。