我最近参与了SwiftUI的开发,并开始以声明式的方式编写代码.但随之而来的是一个困惑.如下所示,我想要(1)加载歌曲数据和(2)在为song赋值之后,通过设置isInfoViewShown来显示视图.

我假设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、合并等的变化,所以从某种意义上说,这些东西确实是相似的.不过,不同之处在于:

一个属性只能有一个didSet,这使得任何数量的观察者都很难注册对该属性的兴趣.

但Combine的最大优势是:Combine管道允许您轻松创建流,例如,将更改流转换为以下流:观察用户输入字符串的更改,go 掉它(速率限制更改,这样我们就不会向服务器发送垃圾邮件),过滤这些更改,以获得至少3个字符长度的任何值,这将生成您可以观察的新流.Map/FlatMap也是一个非常重要的组合运算符,将a的流转换为b的流.还可以使用comineLatest等将两个流合并在一起,这样你就可以获得a的流和b的流,并生成(a,b)的流,然后将其映射到经过验证的c的流.

Swift相关问答推荐

为表单部分赋予背景 colored颜色 /渐变

如何使用RxSwift根据数据数绘制UICollectionView单元格

如何在Swift中获得与Python相同的HMAC—SHA512签名?

使用MKLocalSearch获取坐标

在 SwiftUI 视图中观察 UIViewRepresentable 的 @State var 变化

在SwiftUI中如何预览嵌套的ScrollView,以避免触发可刷新修饰符

在Equatable上引用运算符函数==要求Dictionary.Values符合Equatable

将 Encodable 扩展添加到 Swift 嵌套枚举

如何 for each 用户制作一个单独的按钮,以便在按下它时切换 isFollowingUser Bool 并更改为关注?

Swift Swiftui - 将 colored颜色 保存到 UserDefaults 并从 @AppStorage 使用它

如何在填充上添加 if else 语句? SwiftUI

Swift UI 不重绘 NSViewRepresentable 包装的文本字段

无法增加系统镜像的大小

无法分配给属性:absoluteString是一个只能获取的属性

在 Swift 中,如何查看 Process() 传递给 shell 的字符串?

如何删除桥头而不出错?

Swift中switch 盒的详尽条件

修复 Swift 3 中的警告C-style for Statement is deprecated

TabView 在切换选项卡时重置导航堆栈

如何在 Swift 中从字符串创建类的实例