我最近致力于 SwiftUI 并开始以声明式方式编写代码。但这里出现了困惑。如下所示,在将 song
分配给任何值后,我想 (1) 加载歌曲数据并 (2) 通过设置 isInfoViewShown
显示 View 。
我假设 didSet{}
和 Combine @Published .sink{}
可以互换执行操作。所以我想问一下他们之间有什么区别?在我看来,didSet{}
可以完成 Combine
所做的大部分工作。那么苹果为什么要宣布 Combine
框架呢?
感谢任何帮助。
class InfoViewModel: ObservableObject {
@Published var song: Song? {
didSet { // Here's the didSet{}: [1] load song data
if let song = song {
load(song: song)
}
}
}
private var songSelectedSubscription: AnyCancellable?
@Published var isInfoViewShown: Bool = false
init() { // Here's the Combine @Published .sink{}: [2] show the view
songSelectedSubscription = $song.sink{ self.isInfoViewShown = ($0 == nil ? false : true) }
}
}
最佳答案
当然,观察数据变化的方法有很多,KVO、通知中心、didSet、combine 等,所以从某种意义上来说这些东西确实是相似的。但差异是:
一个属性只能有一个 didSet,这使得任何数量的观察者都很难注册对该属性的兴趣。
但是组合的最大好处是:组合管道允许您轻松创建流,例如,将更改流转换为以下流:观察用户输入字符串的更改,对其进行反跳(速率限制)更改,以便我们不会向服务器发送垃圾邮件),过滤这些更改以获取至少 3 个字符长的任何值,并生成一个您可以观察到的新流。 Map/FlatMap 也是一个非常重要的组合运算符,将 a 流转换为 b 流。还可以使用 mergeLatest 等将两个流合并在一起,这样您就可以获取 a 流和 b 流并创建 (a, b) 流,然后将其映射到经过验证的 c 流。
关于swift - Swift 中 `Combine` 和 `didSet` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73459298/