Swift Combine 发布者订阅者操作者 从入门到精通二
Combine 系列
- Swift Combine 从入门到精通一
1. Combine核心概念
你只需要了解几个核心概念,就能使用好 Combine,但理解它们非常重要。 这些概念中的每一个都通过通用协议反映在框架中,以将概念转化为预期的功能。
这些核心概念是:
- Publisher and Subscriber
- Operator 操作符
- Subjects
2. Publisher and Subscriber
两个关键概念, publisher 和 subscriber,在 Swift 中被描述为协议。
当你谈论编程(尤其是 Swift 和 Combine)时,很多都使用类型描述。 当你说一个函数或方法返回一个值时,该值通常被描述为“此类型之一”。
Combine 就是定义随着时间的推移使用许多可能的值进行操作的过程。 Combine 还不仅仅是定义结果,它还定义了我们如何处理失败。 它不仅讨论可以返回的类型,还讨论可能发生的失败。
2.1 Publisher 发布者
现在我们要引入的第一个核心概念是发布者。 当其被订阅之后,根据请求会提供数据, 没有任何订阅请求的发布者不会提供任何数据。 当你描述一个 Combine 的发布者时,应该用两种相关的类型来描述它:一种用于输出,一种用于失败。
这些通常使用泛型语法编写,该语法在描述类型的文本周围使用 <
和 >
符号。 这表示我们正在谈论这种类型的值的通用实例。 例如,如果发布者返回了一个 String
类型的实例,并且可能以 URLError
实例的形式返回失败,那么发布者可能会用 <String, URLError>
来描述。
2.2 订阅者 Subscriber
与发布者匹配的对应概念是订阅者,是第二个要介绍的核心概念。
订阅者负责请求数据并接受发布者提供的数据(和可能的失败)。 订阅者同样被描述为两种关联类型,一种用于输入,一种用于失败。 订阅者发起数据请求,并控制它接收的数据量。 它可以被认为是在 Combine 中起“驱动作用”的,因为如果没有订阅者,其他组件将保持闲置状态,没有数据会流动起来。
发布者和订阅者是相互连接的,它们构成了 Combine 的核心。 当你将订阅者连接到发布者时,两种类型都必须匹配:发布者的输出和订阅者的输入以及它们的失败类型。 将其可视化的一种方法是对两种类型进行一系列并行操作,其中两种类型都需要匹配才能将组件插入在一起。
2.3 操作符 Operator
第三个核心概念是操作符——一个既像订阅者又像发布者的对象。 操作符是同时实现了 订阅者协议 和 发布者协议 的类。 它们支持订阅发布者,并将结果发送给任何订阅者。
你可以用这些创建成链,用于处理和转换发布者提供的数据和订阅者请求的数据。
我称这些组合序列为管道。
操作符可用于转换值或类型 - 输出和失败类型都可以。 操作符还可以拆分或复制流,或将流合并在一起。 操作符必须始终按输出/失败这样的类型组合对齐。 编译器将强制执行匹配类型,因此类型错误将导致编译器错误(如果幸运的话,会有一个有用的 fixit 片段建议给你解决方案)。
用 swift 编写的简单的 Combine 管道如下所示:
let _ = Just(5) .map { value -> String in // do something with the incoming value here// and return a stringreturn "a string"}.sink { receivedValue in // sink is the subscriber and terminates the pipelineprint("The end result was \(receivedValue)")}
- 管道从发布者
Just
开始,它用它定义的值(在本例中为整数 5)进行响应。输出类型为<Integer>
,失败类型为<Never>
。 - 然后管道有一个
map
操作符,它在转换值及其类型。 在此示例中,它忽略了发布者发出的输入并返回了一个字符串。 这也将输出类型转换为<String>
,并将失败类型仍然保持为<Never>
。 - 然后管道以
sink
订阅者结束。
当你去尝试理解管道时,你可以将其视为由输出和失败类型链接的一系列操作。 当你开始构建自己的管道时,这种模式就会派上用场。 创建管道时,你可以选择操作符来帮助你转换数据、类型或两者同时使用以实现最终目的。 最终目标可能是启用或禁用用户界面的某个元素,或者可能是得到某些数据用来显示。 许多 Combine 的操作符专门设计用来做这些转换。
有许多操作符是以 try
为前缀的,这表示它们返回一个 <Error>
的失败类型。 例如 map
和 tryMap
。 map
操作符可以转换输出和失败类型的任意组合。 tryMap
接受任何输入和失败类型,并允许输出任何类型,但始终会输出 <Error>
的失败类型。
像 map
这样的操作符,你在定义返回的输出类型时,允许你基于提供给操作符的闭包中返回的内容推断输出类型。 在上面的例子中,map
操作符返回一个 String
的输出类型,因为这正是闭包返回的类型。
为了更具体地说明更改类型的示例,我们扩展了值在传输过程中的转换逻辑。此示例仍然以提供类型 <Int, Never>
的发布者开始,并以类型为 <String, Never>
的订阅结束。
SwiftUI-NotesTests/CombinePatternTests.swift
let _ = Just(5) .map { value -> String in switch value {case _ where value < 1:return "none"case _ where value == 1:return "one"case _ where value == 2:return "couple"case _ where value == 3:return "few"case _ where value > 8:return "many"default:return "some"}}.sink { receivedValue in print("The end result was \(receivedValue)")}
Just
是创建一个<Int, Never>
类型组合的发布者,提供单个值然后完成。- 提供给
.map()
函数的闭包接受一个<Int>
并将其转换为一个<String>
。由于<Never>
的失败类型没有被改变,所以就直接输出了。 sink
作为订阅者,接受<String, Never>
类型的组合数据。
当你在 Xcode 中创建管道,类型不匹配时,Xcode 中的错误消息可能包含一个有用的修复建议 fixit。 在某些情况下,例如上个例子,当提供给 map 的闭包中不指定特定的返回类型时,编译器就无法推断其返回值类型。 Xcode (11 beta 2 and beta 3) 显示此为错误消息:
Unable to infer complex closure return type; add explicit type to disambiguate
。 在上面示例中,我们用value → String in
明确指定了返回的类型。
你可以将 Combine 的发布者、操作符和订阅者视为具有两种需要对齐的平行类型 —— 一种用于成功的有用值,另一种用于错误处理。 设计管道时经常会选择如何转换其中一种或两种类型以及与之相关的数据。
参考
https://heckj.github.io/swiftui-notes/index_zh-CN.html
代码
https://github.com/heckj/swiftui-notes
相关文章:
Swift Combine 发布者订阅者操作者 从入门到精通二
Combine 系列 Swift Combine 从入门到精通一 1. Combine核心概念 你只需要了解几个核心概念,就能使用好 Combine,但理解它们非常重要。 这些概念中的每一个都通过通用协议反映在框架中,以将概念转化为预期的功能。 这些核心概念是&#x…...
python 笔记:shapely(形状篇)
主要是点(point)、线(linestring)、面(surface) 1 基本方法和属性 object.area 返回对象的面积(浮点数) object.bounds 返回一个(minx, miny, maxx, maxy)元…...
开源的JS动画框架库介绍
开源的JS动画框架库介绍 在现代网页设计中,动画已经成为提升用户体验的重要手段。它们不仅能够吸引用户的注意力,还能够帮助用户更好地理解和导航网站。JavaScript 动画框架库提供了一套丰富的动画效果,让开发者能够轻松地实现复杂的…...
MATLAB实现随机森林回归算法
随机森林回归是一种基于集成学习的机器学习算法,它通过组合多个决策树来进行回归任务。随机森林的基本思想是通过构建多个决策树,并将它们的预测结果进行平均或投票来提高模型的准确性和鲁棒性。 以下是随机森林回归的主要特点和步骤: 决策树…...
时间序列预测——BiGRU模型
时间序列预测——BiGRU模型 时间序列预测是指根据历史数据的模式来预测未来时间点的值或趋势的过程。在深度学习领域,循环神经网络(Recurrent Neural Networks, RNNs)是常用于时间序列预测的模型之一。在RNNs的基础上,GRU&#x…...
django中实现数据库操作
在Django中,数据库操作通常通过Django的ORM(Object-Relational Mapping)来实现。ORM允许你使用Python类来表示数据库表,并可以使用Python语法来查询和操作数据库。 以下是在Django中实现数据库操作的基本步骤: 一&am…...
使用 FFmpeg 将视频转换为 GIF 动画的技巧
使用 FFmpeg 将视频转换为 GIF 动画 FFmpeg 可以将视频转换为 GIF 动画,方法如下: 1. 准备工作 确保您已经安装了 FFmpeg。 熟悉 FFmpeg 的命令行使用。 了解 GIF 动画的基本知识。 2. 基本命令 ffmpeg -i input.mp4 output.gif 3. 参数说明 -i in…...
2024春晚纸牌魔术原理----环形链表的约瑟夫问题
一.题目及剖析 https://www.nowcoder.com/practice/41c399fdb6004b31a6cbb047c641ed8a?tabnote 这道题涉及到数学原理,有一般公式,但我们先不用公式,看看如何用链表模拟出这一过程 二.思路引入 思路很简单,就试创建一个单向循环链表,然后模拟报数,删去对应的节点 三.代码引…...
HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-静态内存
目录 一、内存管理二、静态内存2.1、静态内存运行机制2.2、静态内存开发流程2.3、静态内存接口2.4、实例2.5、代码分析(待续...)坚持就有收货 一、内存管理 内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包括…...
什么是vite,如何使用
参考: 主要:由一次业务项目落地 Vite 的经历,我重新理解了 Vite 预构建 vite官方文档 为什么有人说 vite 快,有人却说 vite 慢? 深入理解Vite核心原理 面向未来的前端构建工具-vite 聊一聊 Vite 的预构建和二次预构建 …...
基于大语言模型的AI Agents
代理(Agent)指能自主感知环境并采取行动实现目标的智能体。基于大语言模型(LLM)的 AI Agent 利用 LLM 进行记忆检索、决策推理和行动顺序选择等,把Agent的智能程度提升到了新的高度。LLM驱动的Agent具体是怎么做的呢&a…...
23种设计模式之抽象工厂模式
目录 什么是抽象工厂模式 基本结构 基本实现步骤 实现代码(有注释) 应用场景 简单工厂、工厂方法、抽象工厂的区别 什么是抽象工厂模式 抽象工厂模式也是一种创建型设计模式,提供了一系列相关或相互依赖对象的接口,而无需…...
飞天使-linux操作的一些技巧与知识点9-zabbix6.0 容器之纸飞机告警设置
文章目录 zabbix 告警纸飞机方式webhook 方式 告警设置 zabbix 告警纸飞机方式 第一种方式参考 https://blog.csdn.net/yetugeng/article/details/99682432bash-4.4$ cat telegram.sh #!/bin/bashMSG$1TOKEN"61231432278:AAsdfsdfsdfsdHUxBwPSINc2kfOGhVik" CHAT_I…...
京东组件移动端库的使用 Nut-UI
1.介绍 NutUI NutUI-Vue 组件库,基于 Taro,使用 Vue 技术栈开发小程序应用,开箱即用,帮助研发快速开发用户界面,提升开发效率,改善开发体验。 特性 🚀 80 高质量组件,覆盖移动端主…...
用Python来实现2024年春晚刘谦魔术
简介 这是新春的第一篇,今天早上睡到了自然醒,打开手机刷视频就被刘谦的魔术所吸引,忍不住用编程去模拟一下这个过程。 首先,声明的一点,大年初一不学习,所以这其中涉及的数学原理约瑟夫环大家可以找找其…...
TestNG基础教程
TestNG基础教程 一、常用断言二、执行顺序三、依赖测试四、参数化测试1、通过dataProvider实现2、通过xml配置(这里是直接跑xml) 五、testng.xml常用配置方式1、分组维度控制2、类维度配置3、包维度配置 六、TestNG并发测试1、通过注解来实现2、通过xml来…...
###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
前言:感谢您的关注哦,我会持续更新编程相关知识,愿您在这里有所收获。如果有任何问题,欢迎沟通交流!期待与您在学习编程的道路上共同进步。 一. 两个主要软件的介绍 1.KeiluVision5软件 Keil uVision5是一款集成开发…...
Android 9.0 任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态问题的解决
1.概述 在9.0的rom定制化开发中,在点击系统自带的播放器以后,播放音乐的时候,在最近任务栏recents列表中,点击全部清除,发现音乐播放器还在播放音乐,导致出现bug,完整的 解决方法,肯定是需要点击全部清除以后,音乐播放器也被杀掉进程,接下来分析下这个移除任务栏流程…...
【笔记】Helm-5 Chart模板指南-13 调是模版
调试模板 调试模板可能很棘手,因为渲染后的模板发送了kubernetes API server,可能会以格式化以外的原因拒绝YAML文件。 以下命令有助于调试: 1、helm lint 是验证chart是否遵循最佳实践的首选工具。 2、helm template --debug在本地测试渲…...
Gateway反向代理配置
前言 一般而言,反向代理都是在Nginx中来实现的,其实Gateway也可以作为反向代理服务,不过一般不会这么做,只不过最近的项目,在通过Nginx反向代理之后,iPhone手机访问接口代理地址会异常,安卓手机…...
HiveSQL——共同使用ip的用户检测问题【自关联问题】
注:参考文章: SQL 之共同使用ip用户检测问题【自关联问题】-HQL面试题48【拼多多面试题】_hive sql 自关联-CSDN博客文章浏览阅读810次。0 问题描述create table log( uid char(10), ip char(15), time timestamp);insert into log valuesinsert into l…...
猫头虎分享已解决Bug || 修改mongodb3.0副本集用户密码遇到 BeanDefinitionParsingException
博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …...
如何将ChatGPT升级到4.0版本?如何充值?
如何将ChatGPT升级到4.0版本? 在人工智能的世界里,每一个升级都可能带来革命性的变革。ChatGPT的4.0版本无疑是当前最炙手可热的话题之一,那么如何进行升级,体验到这一版所带来的全新特性呢?以下是一步一步的指南。 …...
conda 相关命令
创建并激活环境:打开终端,并创建一个新的conda环境,以确保安装的软件与M1芯片兼容。运行以下命令: conda create -n myenv python这将创建一个名为"myenv"的新环境,并安装Python。然后,激活该环境…...
探索现代Web前端开发框架:选择最适合你的工具
在当今快速发展的Web开发领域,前端开发框架的选择显得尤为关键。这些框架可以帮助我们更高效地构建出交互性强、性能卓越的用户界面。本文将带你了解几个当前最受欢迎的Web前端开发框架,并帮助你根据自己的需求选择最合适的工具。 1. React React由Fac…...
记录一下,我使用stm32实现pwm波输入,以及对频率和占空比的计算,同时通过串口输出(实现-重要)
1,首先看下半物理仿真 看下我的配置: 看下计算方法以及matlab的仿真输出的数据: timer3的ch2是选择高电平,计算频率 timer3的ch1是选择的是低电平,用来计算周期 其中TemPIpre表示的是CH2输出的值, TemPI…...
Spring Cloud使用ZooKeeper作为注册中心的示例
简单的Spring Cloud应用程序使用ZooKeeper作为注册中心的示例: 1.新建模块: 2.勾选依赖: 3.在pom.xml文件中做出部分修改及添加Spring Cloud Zookeeper 依赖版本: 完整pom文件 <?xml version"1.0" encoding&q…...
【项目日记(九)】项目整体测试,优化以及缺陷分析
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:项目日记-高并发内存池⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你做项目 🔝🔝 开发环境: Visual Studio 2022 项目日…...
JavaScript 设计模式之外观模式
外观模式 我们为啥要使用外观模式呢,其实我们在使用各种 js 库的时候常常会看到很多的外观者模式,也正是这些库的大量使用,所以使得兼容性更广泛,通过外观者模式来封装多个功能,简化底层操作方法 const A {g: functi…...
一、基础数据结构——2.队列——3.双端队列和单调队列2
参考资料:《算法竞赛》,罗勇军 郭卫斌 著 本博客作为阅读本书的学习笔记,仅供交流学习。 建议关注 罗勇军老师博客 3. 单调队列与最大子序和问题 不限制子序列长度问题——贪心法或动态规划 HDOJ 1003 MAX SUM Max Sum Time Limit: 2000/10…...
Stable Diffusion 模型下载:Samaritan 3d Cartoon(撒玛利亚人 3d 卡通)
本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十...
【软件工程导论】实验二——编制数据字典(数字化校园系统案例分析)
数字化校园系统案例分析 问题定义实验内容编制内容1数据项数据流处理逻辑数据存储 2外部实体 问题定义 数字化校园系统期望以数字化信息和网络为基础,在计算机和网络技术上建立起对教学、科研、管理、技术服务、生活服务等校园信息的收集、处理、整合、存储、传输和…...
耳机壳UV树脂制作私模定制耳塞适合什么样的人使用呢?
耳机壳UV树脂制作私模定制耳塞适合以下人群使用: 对音质要求高的人:私模定制耳塞能够完美契合用户的耳朵形状,减少漏音和外部噪音的干扰,提供更好的音质体验。需要长时间佩戴耳机的人:私模定制耳塞能够提高佩戴舒适度…...
第三百一十回
我们在上一章回中介绍了"再谈ListView中的分隔线",本章回中将介绍showMenu的用法.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在第一百六十三回中介绍了showMenu相关的内容,它主要用来显示移动PopupMenu在页面中的位置…...
海量数据处理商用短链接生成器平台 - 4
第六章 架构核心技术-池化思想-异步结合 性能优化最佳实践 第1集 RestTemplate里面的存在的问题你知道多少- Broken pipe错误 项目就更新到第六章了,剩下的内容 放百度网盘里面了,需要的来取。 链接:https://pan.baidu.com/s/19LHPw36dsxPB7…...
基于CNN+LSTM深度学习网络的时间序列预测matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 卷积神经网络(CNN) 4.2 长短时记忆网络(LSTM) 4.3 CNNLSTM网络结构 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MA…...
如何控制系统安全 或 控制流氓软件
电脑 出入数据的地方是安全保障的最后一关 比如 网络 , usb 等等 控制联网流氓软件 1 在虚拟机里测试软件是否有恶意行为 恶意行为非常容易发现 比如 破坏文件 修改文件 系统不正常 像蓝屏 等等 2 网络防火墙 这是系统最关键的部分之一 像 windows 一定使用他…...
【Docker】Docker Container(容器)
文章目录 一、什么是容器?二、为什么需要容器?三、容器的生命周期容器OOM容器异常退出容器暂停 四、容器命令详解docker createdocker logsdocker attachdocker execdocker startdocker stopdocker restartdocker killdocker topdocker statsdocker cont…...
Amazon CodeWhisperer 免费 AI 代码生成助手体验分享
今年上半年,亚马逊云科技正式推出了实时AI编程助手 Amazon CodeWhisperer,还提供了供所有开发人员免费使用的个人版版本。经过一段时间的体验,我觉得 CodeWhisperer 可以处理编程工作中遇到的很多问题,并且帮助开发人员提高编程效…...
Spring Cloud Gateway 网关路由
一、路由断言 路由断言就是判断路由转发的规则 二、路由过滤器 1. 路由过滤器可以实现对网关请求的处理,可以使用 Gateway 提供的,也可以自定义过滤器 2. 路由过滤器 GatewayFilter(默认不生效,只有配置到路由后才会生效&#x…...
【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解
1,spring-data-redis官网 1)特点 提供了对不同Redis客户端的整合(Lettuce和Jedis)提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符…...
C语言:内存函数
创作不易,友友们给个三连吧!! C语言标准库中有这样一些内存函数,让我们一起学习吧!! 一、memcpy函数的使用和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); 1.1 使…...
Go+:一种简单而强大的编程语言
Go是一种简单而强大的编程语言,它是在Go语言之上构建的,旨在提供更加强大、灵活和易于使用的编程体验。Go与Go语言共享大部分语法和语义,因此Go开发人员可以很快上手Go,同时也可以使用Go来编写更加简洁和高效的代码。在本文中&…...
【开源】SpringBoot框架开发数字化社区网格管理系统
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、开发背景四、系统展示五、核心源码5.1 查询企事业单位5.2 查询流动人口5.3 查询精准扶贫5.4 查询案件5.5 查询人口 六、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的数字化社区网格管理系统…...
Lua可变参数函数
基础规则 lua传入参数给一个function时采用的是“多余部分被忽略,缺少部分有nil补足”的形式: function f(a, b)return a or b endCALL PARAMETERS f(3) a3, bnil f(3, 4) a3, b4 f(3, 4, 5) a3, b4 (5 is discarded) unpack/pack…...
Nginx实战:3-日志按天分割
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、方式1:定时任务执行分割脚本 1.分割日志脚本 2.添加定时任务 二、方式2:logrotate配置分割 1.logrotate简单介绍 2.新增切割ngi…...
springmvc中的数据提交方式
一、单个数据提交数据 jsp代码: <h2>1单个数据提交</h2> <form action"${pageContext.request.contextPath}/one.action">name<input name"myname"/><br>age<input name"age"><input type&…...
unity2017 遇到visual studio 2017(社区版) 30日试用期到了
安装unity2017 遇到visual studio 2017 30日试用期到了,网上百度搜了好多方法都没有成功。 最后用了这个方法: 1)启动vs2017,在弹出要登录的窗口之前,迅速的点击工具-》选项-》账户,勾选在添加账户或对账户重新进行身…...
Netty应用(六) 之 异步 Channel
目录 12.Netty异步的相关概念 12.1 异步编程的概念 12.2 方式1:主线程阻塞,等待异步线程完成调用,然后主线程发起请求IO 12.3 方式2:主线程注册异步线程,异步线程去回调发起请求IO 12.4 细节注释 12.5 异步的好处…...
STM32CubeMx+MATLAB Simulink串口输出实验,UART/USART串口测试实验
STM32CubeMxMATLAB Simulink串口输出实验...