Combine 框架,从0到1 —— 5.Combine 中的 Subjects
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 —— 5.Combine 中的 Subjects。
内容概览
- 前言
- PassthroughSubject
- CurrentValueSubject
- Subject 作为订阅者
- 常见用法
- 总结
前言
正所谓,工欲善其事,必先利其器。在开始使用 Combine
进行响应式编程之前,建议您先了解 Combine
为您提供的各种发布者(Publishers)、操作符(Operators)、订阅者(Subscribers)。
Subject
是一类比较特殊的发布者,因为它同时也是订阅者。Combine
提供了两类 Subject
:PassthroughSubject
和 CurrentValueSubject
。
如果您想了解更多 Publishers 的用法和注意事项,可以阅读:Combine 框架,从0到1 —— 5.Combine 提供的发布者(Publishers)
PassthroughSubject
PassthroughSubject
可以向下游订阅者广播发送元素。使用 PassthroughSubject
可以很好地适应命令式编程场景。
如果没有订阅者,或者需求为0,PassthroughSubject
就会丢弃元素。
示例代码:
final class SubjectsDemo {
private var cancellable: AnyCancellable?
private let passThroughtSubject = PassthroughSubject<Int, Never>()
func passThroughtSubjectDemo() {
cancellable = passThroughtSubject
.sink {
print(#function, $0)
}
passThroughtSubject.send(1)
passThroughtSubject.send(2)
passThroughtSubject.send(3)
}
}
输出内容:
passThroughtSubjectDemo() 1
passThroughtSubjectDemo() 2
passThroughtSubjectDemo() 3
CurrentValueSubject
CurrentValueSubject
包装一个值,当这个值发生改变时,它会发布一个新的元素给下游订阅者。
CurrentValueSubject
需要在初始化时提供一个默认值,您可以通过 value
属性访问这个值。在调用 send(_:)
方法发送元素后,这个缓存值也会被更新。
示例代码:
final class SubjectsDemo {
private var cancellable: AnyCancellable?
private let currentValueSubject = CurrentValueSubject<Int, Never>(1)
func currentValueSubjectDemo() {
cancellable = currentValueSubject
.sink { [unowned self] in
print(#function, $0)
print("Value of currentValueSubject:", self.currentValueSubject.value)
}
currentValueSubject.send(2)
currentValueSubject.send(3)
}
}
输出内容:
currentValueSubjectDemo() 1
Value of currentValueSubject: 1
currentValueSubjectDemo() 2
Value of currentValueSubject: 2
currentValueSubjectDemo() 3
Value of currentValueSubject: 3
Subject 作为订阅者
示例代码:
final class SubjectsDemo {
private var cancellable1: AnyCancellable?
private var cancellable2: AnyCancellable?
private let optionalCurrentValueSubject = CurrentValueSubject<Int?, Never>(nil)
private func subjectSubscriber() {
cancellable1 = optionalCurrentValueSubject
.sink {
print(#function, $0)
}
cancellable2 = [1, 2, 3].publisher
.subscribe(optionalCurrentValueSubject)
}
}
optionalCurrentValueSubject
可以作为一个订阅者去订阅序列发布者 [1, 2, 3].publisher
发送的元素。
输出内容:
subjectSubscriber() nil
subjectSubscriber() Optional(1)
subjectSubscriber() Optional(2)
subjectSubscriber() Optional(3)
常见用法
在使用 Subject
时,我们往往不会将其暴露给调用方。这时候,可以使用 eraseToAnyPublisher
操作符来隐藏内部的 Subject
。
示例代码:
struct Model {
let id: UUID
let name: String
}
final class ViewModel {
private let modelSubject = CurrentValueSubject<Model?, Never>(nil)
var modelPublisher: AnyPublisher<Model?, Never> {
return modelSubject.eraseToAnyPublisher()
}
func updateName(_ name: String) {
modelSubject.send(.init(id: UUID(), name: name))
}
}
外部调用者无法直接操控 ViewModel
内部的 Subject
,这样可以让 ViewModel
更好地面对将来可能的改动。
外部调用者只需要知道 modelPublisher
是 AnyPublisher<Model?, Never>
类型的发布者即可,无论内部采用了 CurrentValueSubject
还是 PassthroughSubject
甚至是其他的发布者。
总结
相比于其他的发布者来说, Subject
是比较容易理解的,而且也是最常用到的。
只可惜,对比 Rx
提供的 Subject,Combine 中的 Subject 无法设置缓冲的大小。也许某天苹果会对此做出调整吧~
Combine 框架,从0到1 —— 5.Combine 中的 Subjects的更多相关文章
- Combine 框架,从0到1 —— 1.核心概念
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 1.核心概念. 内容概览 前言 核心概念 RxSwift Combine 总结 参考内容 ...
- Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 2.通过 ConnectablePublisher 控制何时发布. 内容概览 前言 使用 ma ...
- Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 3.使用 Subscriber 控制发布速度. 内容概览 前言 在发布者生产元素时消耗它们 使 ...
- Combine 框架,从0到1 —— 4.在 Combine 中使用通知
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中使用通知. 内容概览 前言 让通知处理代码使用 Combine 总结 ...
- Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中使用计时器. 内容概览 前言 使用计时器执行周期性的工作 将计时器转换为计时 ...
- Combine 框架,从0到1 —— 4.在 Combine 中使用 KVO
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中使用 KVO. 内容概览 前言 用 KVO 监控改动 将 KVO 代 ...
- Combine 框架,从0到1 —— 4.在 Combine 中执行异步代码
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中执行异步代码. 内容概览 前言 用 Future 取代回调闭包 用输出类型( ...
- Combine 框架,从0到1 —— 5.Combine 提供的发布者(Publishers)
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 提供的发布者(Publishers). 内容概览 前言 Just Future D ...
- Combine 框架,从0到1 —— 5.Combine 常用操作符
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 常用操作符. 内容概览 前言 print breakpoint handleEve ...
随机推荐
- 团队作业3:需求改进&系统设计
一.需求&原型改进: 1.1 选题需求改进 用户:同学你好,有什么事我们能帮到你 我:我要说的事……(咽口水)你们千万别害怕 用户:我们是杠精,我们不会怕,您请说 我:我们要做一个roguel ...
- 迷上我成真恋爱学心理学挽回她PDF文档资料完整版情感技巧脱单教程
迷上我成真恋爱学心理学挽回她PDF文档资料完整版情感技巧脱单教程 成真迷上我偷听女人心挽回她课程 百度网盘迷上我教程pdf地址 百度网盘挽回她教程pdf+视频的地址 备用地址淘宝百度网盘发货地址 百度 ...
- seo成功案例的背后秘密
http://www.wocaoseo.com/thread-319-1-1.html 刚刚在seo群内一个企业主告诉我,他在淘宝找了做seo排名的,在交了首付后,对方却跑路了.对方刚刚在淘宝开店,然 ...
- eslint 的 使用常见问题(一)
在source tree 远程拉去一个项目,然后无缘无故 代码各处飘红 ,然后看了很是烦躁.碰见一下几个问题,后续持更 一.升级es6 出现这个问题的原因:let是EcmaScript 6 里面才有的 ...
- 在centos6.5下搭建lnmp
1.查看环境: [root@localhost /]# cat /etc/redhat-release CentOS release 6.5 (Final) 2.关掉防火墙(需要到国外地址下载软件 ...
- Azure Blob (三)参数设置说明
一,引言 上一篇将 Azure Blob 存储的时候,有使用到一个 .NET Core Web 项目,通过代码的方式进行操作 Azure Blob 的数据,接着上一篇的内容,今天继续看一下代码,具体 ...
- Mybatis联合查询(一)
Mybatis的简单联合查询操作: 实体类: Employee: package com.test.mybatis; public class Employee { private Integer i ...
- 教你用OpenCV 和 Python给证件照换底色(蓝底 <->红底->白底)
在我们的生活中常常要用到各种底色要求的证件电子照,红底.蓝底.或者白底,而假如你手上只有一种底色的证件照,你又不想再去拍又不会PS怎么办?今天教你们用OpenCV和Python给你的证件照换底色. P ...
- 存储过程中拼接SQL语句
很多时候我们需要利用参数在存储过程中重新组织SQL语句,在存储过程中拼接的SQL语句只是一个字符串,不会被直接执行,所以加一个execute执行它就可以了.具体看如下演示代码: 代码: set ANS ...
- Solon详解(三)- Solon的web开发
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...