Combine简介
Combine是一个苹果用来处理事件的新的响应式框架,支持iOS 13及以上版本。
你可以使用Combine去统一和简化在处理类似于target-action,delegate,kvo等事情的代码。
iOS目前已经有第三方的响应式框架了,如:RxSwift、ReactiveCocoa,但是苹果现在发布了自己的新的框架。
它提供了一种声明式、函数式的编程方式,可以让开发者更加简单、高效地处理异步数据流。

Combine核心概念

Combine的核心概念是Publisher、Subscriber和Operator。发布者,订阅者和中间操作者。
发布者Publisher:可以将值或错误发送给订阅者,并且在完成或取消时,向订阅者发送相应的消息。
订阅者Subscriber:接收发布者发送的值、错误和完成信息,并进行相应的处理。
操作符Operator:用来对数据流进行转换、过滤、合并等处理,Combine框架中提供了很多操作符,例如map、filter、merge等。
当一个Publisher发布一个事件时,Subscriber会被通知这个事件,并执行相应的操作。
一个Subscriber可以订阅多个Publisher,并且每个Publisher都可以同时拥有多个Subscriber。当所有的Subscriber都取消订阅时,Publisher会停止发布事件。
Operator可以对事件流进行各种操作,包括数据转换、过滤、组合等。比如,map操作可以将一个事件流中的元素转换成另一个类型,filter操作可以过滤出符合条件的元素,merge操作可以将多个事件流合并成一个事件流等。
 
map操作符可以将数据流中的值进行转换,返回一个新的数据流。例如,将一个字符串转换成大写形式:
let stringPublisher = Just("hello, world!")
let uppercasedPublisher = stringPublisher.map { $0.uppercased() }
filter对数据流中的值进行过滤,返回一个新的数据流。例如,过滤掉数组中的偶数:
let arrayPublisher = [1, 2, 3, 4, 5].publisher
let oddPublisher = arrayPublisher.filter { $0 % 2 != 0 }
merge对数据流进行合并,生成一个数据流。例如,将两个发布者合并成一个:
let publisher1 = Just("hello")
let publisher2 = Just("world")
let mergedPublisher = Publishers.Merge(publisher1, publisher2)
下面是一个简单的例子,展示了如何使用Combine来监听一个UITextField的文本输入
import UIKit
import Combine class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! var cancellables = Set<AnyCancellable>() override func viewDidLoad() {
super.viewDidLoad() // 创建一个订阅者,打印出文本输入的内容
let subscriber = Subscribers.Assign(object: self.textField, keyPath: \.text) // 订阅文本输入框的文本变化事件
self.textField.textPublisher(for: .editingChanged)
.map { $0.text ?? "" }
.subscribe(subscriber)
.store(in: &cancellables)
}
} extension UITextField {
func textPublisher() -> AnyPublisher<String, Never>
{
NotificationCenter.default
.publisher(for: UITextField.textDidChangeNotification, object: self)
.map {($0.object as? UITextField)?.text ?? ""}
.eraseToAnyPublisher()
}
}
AnyCancellable
Combine 中还定义了一个 AnyCancellable 类,实现了 Cancellable 协议,特点是会在该类析构时自动执行 cancel 方法。
在实际开发中,当 Subscriber 在某个时候不想接收 Publisher 发布的数据时,可以取消订阅以释放资源。
Combine 中提供了 Cancellable 协议,该协议中定义了一个 cancel 方法,用于取消订阅流程。
import Combine
let subject = PassthroughSubject<String, Never>() // 创建PassthroughSubject
// 订阅
let subscription = subject.sink(receiveCompletion: { _ in
print("receiveCompletion")
}, receiveValue: { value in
print(value) })
// 发送数据
subject.send("hello")
// 中途取消订阅
subscription.cancel()
// 后面发送的数据都会失败
subject.send("world")
subject.send(completion: .finished)
/* 输出:
hello
*/
可以理解为 AnyCancellable是一种管理订阅状态的工具,能根据开发者需要在某个时段切断 Publisher和 Subscriber的联系。
AnyCancellable 的一个应用就是可以在某种情况下中断网络请求,实现如下:
import UIKit
import Combine
let dataPublisher = URLSession.shared.dataTaskPublisher(for: URL(string: "https://louyu.cc")!)
let cancellableSink = dataPublisher.sink { completion in
switch completion {
case .finished:
break
case .failure(let error):
print("error: \(error)")
break
}
} receiveValue: { value in
print("received \(value)")
}
cancellableSink.cancel() //取消网络请求
参考文章地址:
https://www.jianshu.com/p/1dc27229a533
https://louyu.cc/articles/ios-swift/2021/03/?p=2865/
 

Swift中发布-订阅框架Combine的使用的更多相关文章

  1. 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

    一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...

  2. 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载

    一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用 ...

  3. 基于.NET Socket Tcp的发布-订阅框架

    基于.NET Socket Tcp的发布-订阅框架 一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已 ...

  4. react 中发布订阅模式使用

    react 中发布订阅模式使用 场景 怎么能将设计模式应用到我们的 React 项目中?以前一直在思考这个问题. 场景一 模块 A 模块 B 需要用到同一个数据 data,A 和 B 都会修改这份数据 ...

  5. 理解JavaScript设计模式与开发应用中发布-订阅模式的最终版代码

    最近拜读了曾探所著的<JavaScript设计模式与开发应用>一书,在读到发布-订阅模式一章时,作者不仅给出了基本模式的通用版本的发布-订阅模式的代码,最后还做出了扩展,给该模式增加了离线 ...

  6. python中发布订阅和主从配置

    发布订阅 发布者不是计划发送消息给特定的接收者(订阅者),而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅 订阅者对一个或多个频道感兴趣,只需接收感兴趣的消息,不需要知道什么样的发布者发布的 ...

  7. java 多线程 发布订阅模式:发布者java.util.concurrent.SubmissionPublisher;订阅者java.util.concurrent.Flow.Subscriber

    1,什么是发布订阅模式? 在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者).而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话 ...

  8. kafka 基础知识梳理-kafka是一种高吞吐量的分布式发布订阅消息系统

    一.kafka 简介 今社会各种应用系统诸如商业.社交.搜索.浏览等像信息工厂一样不断的生产出各种信息,在大数据时代,我们面临如下几个挑战: 如何收集这些巨大的信息 如何分析它 如何及时做到如上两点 ...

  9. Springboot+Redis(发布订阅模式)跨多服务器实战

    一:redis中发布订阅功能(http://www.redis.cn/commands.html#pubsub) PSUBSCRIBE pattern [pattern -]:订阅一个或者多个符合pa ...

  10. Redisson 分布式锁实现之前置篇 → Redis 的发布/订阅 与 Lua

    开心一刻 我找了个女朋友,挺丑的那一种,她也知道自己丑,平常都不好意思和我一块出门 昨晚,我带她逛超市,听到有两个人在我们背后小声嘀咕:"看咱前面,想不到这么丑都有人要." 女朋友 ...

随机推荐

  1. JSP 学习笔记 | 三、EL 表达式简述

    前文:JSP 学习笔记 | 二.JSP 脚本 & 案例实现 & 缺点分析 前文:JSP 学习笔记 | 一.JSP 原理理解 概述 EL(全称Expression Language )表 ...

  2. MySQL 的 crash-safe 原理解析

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/5i9wmJs4_Er7RaYfNnETyA作者:xieweipeng MySQL作为当下最流行 ...

  3. vue3调用高德地图,实现地址,经纬度填写

    父组件引用高德地图: 1 <template> 2 <div class="wrapper"> 3 <div class="box" ...

  4. HUD 5773 LIS(最长上升序列)

    ***关于lower_bound()的用法参见:http://blog.csdn.net/niushuai666/article/details/6734403 lower_bound用法:函数low ...

  5. excel如何自动获取本周工作日的日期显示作为标题(周一至周五)

    一.背景: 每周发周报的标题格式为:本周一到本周五的日期内容,如下:但是每隔一周发送的时候需要改一下周报标题里面的日期,比较麻烦目前的需求是通过函数自动化生成,根据当前的日期去定位出本周一的日期以及本 ...

  6. spring boot 整合kafka

    本文为博主原创,未经允许不得转载: 1. 引入spring boot kafka依赖 <dependency> <groupId>org.springframework.kaf ...

  7. 针对docker中的mongo容器增加鉴权

    1. 背景 业务方的服务器经安全检查,发现以docker容器启动的mongo未增加鉴权的漏洞,随优化之 2. 配置 mongo以docker compose方式启动,镜像的版本号为4.2.6,dock ...

  8. APB Slave Design

    APB Slave Design module apb_slave #( REG1_ADDR = 8'h00, REG2_ADDR = 8'h04, REG3_ADDR = 8'h08 ) ( // ...

  9. 【lvgl-micropython】官方源码之ports/unix 编译报错

    lv_micropython/ports/unix make 报错 编译环境如下 这是缺少SDL2库导致的 sudo apt-get install libsdl2-2.0 sudo apt-get ...

  10. [转帖]iptables规则链执行顺序

    https://www.cnblogs.com/yum777/articles/8514636.html iptables 是采用规则堆栈的方式来进行过滤,当一个封包进入网卡,会先检查 Prerout ...