本文首发于 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,只需将 TimerscheduledTimer(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 中使用计时器的更多相关文章

  1. Combine 框架,从0到1 —— 1.核心概念

      本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 1.核心概念.     内容概览 前言 核心概念 RxSwift Combine 总结 参考内容 ...

  2. Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布

      本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 2.通过 ConnectablePublisher 控制何时发布.   内容概览 前言 使用 ma ...

  3. Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度

      本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 3.使用 Subscriber 控制发布速度.   内容概览 前言 在发布者生产元素时消耗它们 使 ...

  4. Combine 框架,从0到1 —— 4.在 Combine 中使用通知

      本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中使用通知.   内容概览 前言 让通知处理代码使用 Combine 总结 ...

  5. Combine 框架,从0到1 —— 4.在 Combine 中使用 KVO

      本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中使用 KVO.   内容概览 前言 用 KVO 监控改动 将 KVO 代 ...

  6. Combine 框架,从0到1 —— 4.在 Combine 中执行异步代码

    本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 4.在 Combine 中执行异步代码. 内容概览 前言 用 Future 取代回调闭包 用输出类型( ...

  7. Combine 框架,从0到1 —— 5.Combine 提供的发布者(Publishers)

    本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 提供的发布者(Publishers). 内容概览 前言 Just Future D ...

  8. Combine 框架,从0到1 —— 5.Combine 中的 Subjects

    本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 中的 Subjects. 内容概览 前言 PassthroughSubject C ...

  9. Combine 框架,从0到1 —— 5.Combine 常用操作符

    本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 5.Combine 常用操作符. 内容概览 前言 print breakpoint handleEve ...

随机推荐

  1. 2020-06-15:Redis分布式锁怎么解锁?

    福哥答案2020-06-15: 答案来自群成员:1.setnx:del2.set:lua+del3.redisson:@Overridepublic void unlock(String lockKe ...

  2. 从一次外卖到对oauth2.0的思考

    别问oauth1.0哪去了,问就是不好讲. 1. 外卖并不好吃   今天下班得早,想吃顿好的,于是就点了一份外卖,过了一会儿,外卖到了,但是在小区大门被堵住了,我亲自远程开门后才能进来,又过了一会,被 ...

  3. vue element Admin - 修改浏览器标签名 + 添加tagView标签 +固定导航头部 + 添加侧边栏Logo

    1 .修改浏览器标签名称: 修改浏览器标签名称在文件:\src\settings.js   image.png 2 .修改固定头部Header和侧边栏 Logo:   image.png 1)侧边栏文 ...

  4. Linux内核之 内核同步

    上文我们介绍过进程调度,Linux内核从2.6版本开始支持内核抢占,所以内核很多代码也需要同步保护. 一.同步介绍 1.临界区与竞争条件 所谓临界区(critical regions)就是访问和操作共 ...

  5. 《从缺陷中学习CC++》总结

    从缺陷中学习CC++总结 从本质上来说,这就是一个CC++的错题集.全书中包括63个问题引发的错误,即书名中的缺陷.共分为10章,每一张还有一个比较经典的小结,个人感觉这本书只需要仔细看一下每一章后面 ...

  6. PythonCrashCourse 第十章习题

    在文本编辑器中新建一个文件,写几句话来总结一下你至此学到的Python知识,其中每一行都以"In Python you can"打头.将这个文件命名为 learning_pytho ...

  7. DataNode(面试开发重点)

    1 DataNode工作机制 DataNode工作机制,如图所示. 1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和 ...

  8. Python方法oslo_service.loopingcall.LoopingCallDone代码示例

    Python方法oslo_service.loopingcall.LoopingCallDone代码示例 demo: from oslo_service import loopingcall def ...

  9. cenos 7 mysql

    CentOS 7的yum源中貌似没有正常安装mysql时的mysql-sever文件,需要去官网上下载 # wget http://dev.mysql.com/get/mysql-community- ...

  10. 自我介绍网页填写表格PHP,JavaScript,html,css代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...