Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 —— 4.在 Combine 中使用计时器。
内容概览
- 前言
- 使用计时器执行周期性的工作
- 将计时器转换为计时器发布者(
Timer.TimerPublisher) - 总结
前言
计时器是苹果开发者常用的功能。如果你的应用使用 Foundation 框架中的计时器 Timer 来周期性地执行某些操作,你可以用 Combine 简化这些代码。
现在,让我们来学习如何使用 Combine 处理计时器,并将已有的计时器处理代码迁移到 Combine。
使用计时器执行周期性的工作
对于 iOS 开发人员而言,以下代码一定非常眼熟:
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
self.myDispatchQueue.async() {
self.myDataModel.lastUpdated = Date()
}
}
}
以上代码使用 scheduledTimer(withTimeInterval:repeats:block:) 来实现每秒钟在 myDispatchQueue 中更新 self.myDataModel.lastUpdated 的功能。
将计时器转换为计时器发布者(Timer.TimerPublisher)
要将以上代码迁移到 Combine,只需将 Timer(scheduledTimer(withTimeInterval:repeats:block:)的返回值) 替换为 Timer.TimerPublisher。调用 Timer. publish(every:tolerance:on:in:options:) 方法即可创建一个发布者。
每次底层的计时器(Timer)触发时,发布者都会发出一个新的日期(Date)实例,该日期代表计时器触发的瞬间。然后,你可以将 Combine 操作符应用到这个日期实例上,最终将这个发布者和一个订阅者(如:sink(receiveValue:) 或 assign(to:on:))连接。
由于
Timer.TimerPublisher遵从ConnectablePublisher协议,因此在您显式地连接之前,它不会产生任何元素。为此,可以通过手动调用connect()或使用autoconnect()运算符在订阅者连接时自动连接来实现。关于ConnectablePublisher的用法,可以参考 这篇文章。
下一个示例将展示如何使用 Timer.TimerPublisher 替换上一个示例。它使用 Combine 的操作符来完成上一个示例中的闭包中的操作:
var cancellable: Cancellable?
override func viewDidLoad() {
super.viewDidLoad()
cancellable = Timer.publish(every: 1, on: .main, in: .default)
.autoconnect()
.receive(on: myDispatchQueue)
.assign(to: \.lastUpdated, on: myDataModel)
}
在这个例子中,Combine 操作符替换了上一个示例的闭包中的所有行为:
receive(on:options:)操作符确保了后续操作在指定的调度队列中执行,它替代了前面用到的async()调用;assign(to:on:)操作符通过键路径来更新数据模型的lastUpdated属性;
使用 Combine 来简化你的代码时,你会发现 Timer.TimerPublisher 会产生新的 Date 实例作为其输出类型。而第一个示例的闭包是将 Timer 本身作为其参数,因此它必须手动创建新的 Date 实例。
总结
使用 Combine 来简化你的计时器代码时,你会发现:
- 代码易读性明显提升;
- 线程切换变得更简单;
- 数据模型的更新可以通过键路径(
key path)来简化;
朋友,行动起来吧!把现有项目中的旧代码重构成使用 Combine 的代码~
本文内容来源:
Replacing Foundation Timers with Timer Publishers
Combine 框架,从0到1 —— 4.在 Combine 中使用计时器的更多相关文章
- 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 中使用 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 中的 Subjects
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 中的 Subjects. 内容概览 前言 PassthroughSubject C ...
- Combine 框架,从0到1 —— 5.Combine 常用操作符
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 常用操作符. 内容概览 前言 print breakpoint handleEve ...
随机推荐
- 链表(python)
一.链表和数组 在编写代码中,我们储存的数据是存储于内存当中,内存就像一块块并列排序的小方盒,每个小方盒都有自己地址,我们储存的数据就在这样一个个小方盒当中. 这些数据存放的结构有两种基本方式,数组和 ...
- golang 浮点型
目录 前言 1.三要素 2.表现形式 3.类型 4.精度 5.格式化 6.使用细节 跳转 前言 不做文字的搬运工,多做灵感性记录 这是平时学习总结的地方,用做知识库 平时看到其他文章的相关知识,也会增 ...
- Mybatis——ResultMap(结果集映射)的使用
ResultMap的使用 在Mybatis中,可以使用resultMap(结果集映射)作为sql的返回类型 一般用来解决如下问题: 数据库表字段名和实体类属性名不一致的问题: 多对一问题: 例如:多个 ...
- Jsp内置对象application之统计浏览网页的次数
<% Object obj = application.getAttribute("count"); if(obj !=null){ Integer sum = (Integ ...
- 收集整理element-ui 表格组件的常用操作方法
一.简单的表格行内编辑效果 原理是通过Css控制绑定的输入控件与显示值,在选中行样式下对控件进行隐藏或显示. 1.注意下样式的设置 2.change事件 @change="handleEdi ...
- Goland 生成可执行文件
Goland通过调用go build 生成可执行文件. 默认Goland是可以执行程序,但你找不到可执行文件. 你需要自定义配置文件. 创建go build配置文件 Run kind 选Directo ...
- Nmap在实战中的高级用法(详解)
@ 目录 Nmap在实战中的高级用法(详解) Nmap简单的扫描方式: 一.Nmap高级选项 1.查看本地路由与接口 2.指定网口与IP地址 3.定制探测包 二.Nmap扫描防火墙 1.SYN扫描 2 ...
- 关于MapReduce默认分区策略
MapReduce默认分区策略 mapreduce 默认的分区方式是hashPartition,在这种分区方式下,KV对根据key的hashcode值与reduceTask个数进行取模,决定该键值对该 ...
- 什么?Java9这些史诗级更新你都不知道?Java9特性一文打尽!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- Jmeter系列(56)- 详解 Weighted Switch Controller 权重控制器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 它能分配其子项目(Child ...