Combine 通过 PassthroughRelay 的数据发布

在这个ViewModel代码中,allCreations、allCreationsRelay 和 allCreationsPublisher 是三个关联但作用不同的变量。


// 变量 allCreations
private var allCreations: [CreationModel] = []

// 变量的PassthroughRelay
private let allCreationsRelay = PassthroughRelay<[CreationModel]>()

// 变量对应的AnyPublisher
var allCreationsPublisher: AnyPublisher<[CreationModel], Never> {
   allCreationsRelay.eraseToAnyPublisher()
}

------------------------------

// 订阅
allCreationsPublisher
                .map({ $0.filter({ $0.isDot }).count })
                .removeDuplicates()
                .sink(receiveValue: { [weak self] count in
                    self?.dotNumber = count
                }).store(in: &cancellables)
  • allCreations:
    这是一个普通的数组,类型为 [CreationModel],它存储了所有的作品数据;

  • allCreationsRelay:
    allCreationsRelay 是一个 PassthroughRelay<[CreationModel]>,它是一个 Combine 的专用对象,用来“传递”数据;

  • allCreationsPublisher:
    allCreationsPublisher 是 allCreationsRelay.eraseToAnyPublisher() 的结果,它将 allCreationsRelay 转换为一个可以公开订阅的 Publisher。

为什么不能直接订阅allCreationsRelay?

针对 allCreationsRelayallCreationsPublisher 的存在意义:两个变量之间的关系实际上是通过 PassthroughRelayAnyPublisher 来实现的。

  1. PassthroughRelay 的作用
    allCreationsRelay 是一个 PassthroughRelay<[CreationModel]>,这实际上是一个对象,它用于在内部管理数据流。PassthroughRelay 是一个特殊的类型,它结合了 PassthroughSubjectRelay 的特性,允许我们发布一个事件流,但它本身并不遵循公开发布的规范,不能直接作为公共 API 使用。

  2. 封装和数据流控制
    allCreationsRelay 只是一个底层的容器,充当了对外界通知的角色。为了提供更强的封装性、解耦和可测试性,我们通常会暴露一个 AnyPublisher 类型的数据流,而不是直接暴露一个 PassthroughRelay 对象。通过暴露 allCreationsPublisherAnyPublisher<[CreationModel], Never>),外部只能订阅这个封装后的流,而不需要关心它如何被更新。这样做符合封装和数据流的控制原则。

  3. AnyPublisher 的意义
    allCreationsPublisher 是一个通过 .eraseToAnyPublisher() 封装的 AnyPublisher,它是 PassthroughRelay 公开的接口。AnyPublisher 封装了 PassthroughRelay,让外部只能订阅、观察这个流,而不能修改它。这种方式可以保证外部只能读取数据,而不会意外修改它,增加了代码的健壮性。

allCreationsRelay 是一个内部的可变数据流,供内部使用来发布数据变更;
allCreationsPublisher 是一个对外公开的、封装后的不变数据流,它用于外部订阅者接收数据变化。

通过这样的封装,ViewModel 内部可以自由地更新 Relay 数据,而外部的订阅者只能监听变化,无法直接修改数据流,这有助于提高代码的清晰度和可维护性。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容