为啥在初始化程序中设置时调用 didSet?
Posted
技术标签:
【中文标题】为啥在初始化程序中设置时调用 didSet?【英文标题】:Why is didSet called when set inside an initializer?为什么在初始化程序中设置时调用 didSet? 【发布时间】:2019-12-22 22:47:39 【问题描述】:我正在玩 SwiftUI,我有一个看起来像这样的类:
class Foo: ObservableObject
@Published var foo: Int! // Implicit unwrapped optional
didSet
print("foo")
init()
self.foo = 1
didSet 总是被调用。根据Apple docs,不应调用它。 @Published
属性包装器有什么特别之处吗?
【问题讨论】:
在 Xcode 11.2.1 上测试 -didSet
在代码快照的初始化期间不会被调用。以及没有@Published
。
我在 Xcode 11.3 (11C29) 上测试过 - 在代码快照的初始化过程中不会调用 didSet
(正如 @Asperi 所写)
对不起,我打错了。检查有问题的更新代码。 @Asperi
【参考方案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) 在两种情况下按指令执行,您可以在运行时查看所有图片...非常有趣内部结构。
【讨论】:
【参考方案2】:规则是在初始化期间不调用 setter 观察者。但是当你设置这个属性时,初始化就结束了!该属性已被赋予其初始值,即nil
。因此,即使您在 init
方法中,您也不是“在初始化期间”并且 setter 观察者运行。
【讨论】:
【参考方案3】:在这里找到答案,当使用隐式解包变量时,它会离开初始化范围,因此 didSet 被称为:https://***.com/a/25231068/294661
【讨论】:
以上是关于为啥在初始化程序中设置时调用 didSet?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 UICollectionView 支持方法仅在我的 ViewController 设置为初始视图控制器时调用?