我发现自己又回到了这篇文章,所以我想对@Published 和CurrentValueSubject 之间的区别添加一些额外的见解。
可以在@Published 的文档中找到一个主要区别:
当属性发生变化时,会在属性的 willSet 块中进行发布,这意味着订阅者会在新值被实际设置在属性上之前收到它。
此外,Swift Forums 上的对话请注意,@Published 旨在与 SwiftUI 一起使用。
关于@Published 在其属性的willSet 块中发布,请考虑以下示例:
class PublishedModel {
@Published var number: Int = 0
}
let pModel = PublishedModel()
pModel.$number.sink { number in
print("Closure: \(number)")
print("Object: \(pModel.number) [read via closure]")
}
pModel.number = 1
print("Object: \(pModel.number) [read after assignment]")
这会产生以下输出:
Closure: 0
Object: 0 [read via closure]
Closure: 1
Object: 0 [read via closure]
Object: 1 [read after assignment]
将此与另一个示例进行对比,在该示例中,除了将 @Published 替换为 CurrentValueSubject 之外,我们保持相同:
class CurrentValueSubjectModel {
var number: CurrentValueSubject<Int, Never> = .init(0)
}
let cvsModel = CurrentValueSubjectModel()
cvsModel.number.sink { number in
print("Closure: \(number)")
print("Object: \(cvsModel.number.value) [read via closure]")
}
cvsModel.number.send(1)
print("Object: \(cvsModel.number.value) [read after assignment]")
输出:
Closure: 0
Object: 0 [read via closure]
Closure: 1
Object: 1 [read via closure] // <— Here is the difference
Object: 1 [read after assignment]
将number 更新为1 后,读取对象的CurrentValueSubject 的值属性在 闭包打印新值而不是旧值,就像@Published 一样强>。
总之,在您的ObservableObjects 中使用@Published 来获取您的SwiftUI 视图。如果您希望创建某种模型对象,其实例属性包含当前值并且也在设置后发布它的更改,请使用CurrentValueSubject。