专栏首页学海无涯Combine-Scheduler

Combine-Scheduler

如果说 Publisher 决定了发布什么样的 (what) 数据的话,Scheduler(调度器) 所要解决的就是两个问题:在什么地方 (where),以及在什么时候 (when) 来发布数据和接收数据。我们都知道,在 iOS 开发中如果需要更新 UI,需要保证相关操作发生在主线程。在 Combine 中如果数据流前面的 Publisher 是在后台线程进行操作,那么在订阅时,当状态的变化会更新 UI 时,需要将数据流中接收数据的线程切换到主线程。

内置Scheduler

Scheduler在是一个协议,遵守了该协议的内置 Scheduler 有:

  • DispatchQueue
  • OperationQueue
  • RunLoop
  • ImmediateScheduler:立即执行同步操作, 如果使用它执行延迟的工作,会报错。

使用RunLoop.main, DispatchQueue.mainOperationQueue.main来执行与 UI 相关的操作。

receive与subscribe

默认情况下,当前的 Scheduler 与最初产生数据的 Publisher 所在的 Scheduler 相同。但是实际情况往往是在整个数据流中需要切换 Scheduler,所以 Combine 提供了两个函数来设置 Scheduler。

receive(on:)

定义了在哪个 Scheduler 完成 Publisher 的订阅。(在哪里接收数据

import Combine

let subscription = Just(1)
    .map { _ in print(Thread.isMainThread) } 
    .receive(on: DispatchQueue.global())
    .map { print(Thread.isMainThread) }
    .sink { print(Thread.isMainThread) }

/* 输出
 true
 false
 false
 */

subscribe(on:)

定义了在哪个 Scheduler 来发布 Publisher,它的位置顺序不会影响结果。(在哪里发布数据

import Combine

let subscription = Just(1)
    .subscribe(on: DispatchQueue.global())
    .map { _ in print(Thread.isMainThread) } 
    .sink { print(Thread.isMainThread) }

/* 输出
false
false
*/


let subscription = Just(1)
    .subscribe(on: DispatchQueue.global())
    .map { _ in print(Thread.isMainThread) }
    .receive(on: DispatchQueue.main)
    .sink { print(Thread.isMainThread) }

/* 输出
false
true
*/

案例

import UIKit
import Combine

let subscription = URLSession.shared
    .dataTaskPublisher(for: URL(string: "https://www.example.com")!)
    .compactMap { String(data: $0.data, encoding: .utf8) }
    .receive(on: RunLoop.main) // 回到主线程更新UI
    .sink {
        textView.text = $0
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Swift4+Xcode10+iOS开发基础教程(上)在线课程

    学习任何一门编程语言目的是能够用它进行相应的开发工作,在Swift语法学习完成以后,接下来就是用它来进行iOS或者Mac开发。本人自己录制的Swift4+Xco...

    YungFan
  • iOS开发之蓝牙(一)

    在iOS开发中,我们最常用的蓝牙开发框架应该是Core Bluetooth,因为它可以与第三方蓝牙设备交互(必须要支持蓝牙4.0),蓝牙4.0以低功耗著称,所以...

    YungFan
  • 39.Swift学习之常用数据类型

    YungFan
  • 一个extension让你在Swift中用NSTimer更少操心

    它会持有target的引用计数,不出意外的话你的target还会持有它的引用计数。另外,还会被runloop持有它的引用计数。

    剑行者
  • SpringMVC的初始

    1:其实一开始对SSH和SSM并不是很熟悉的,对SSH可能熟悉些(Struts,Spring,Hibernate)这三个框架。但是由于框架的更新,和出现了更好的...

    别先生
  • SpringMVC框架(一)

    SpringMVC最核心:DispatcherServlet SpringMVC环境搭建: 结构: ? 过程:   1.导包   2.声明SpringMVC核心...

    二十三年蝉
  • SpringMVC系列知识:(二)原生springMVC的开发流程

    先创建一个maven项目,在pom里面将springmvc需要的依赖导入,因为这个maven项目是一个web项目,所以有web这个目录,首先之前的web项目是在...

    一天不写程序难受
  • spring mvc 3 最简单demo

    这两天再看spring mvc,想再网上找一个demo,感觉国内的demo都太复杂了。后来在国外网站上发现了一个比较简单,应该说是最简单的spring mvc的...

    py3study
  • server 2016 安装WDS服务并下发操作系统

    WDS的全称为Windows部署服务,主要应用于大中型网络中的计算机操作系统的批量化部署。通过使用WDS可以管理系统映像和无人参与安装脚本,并提供人工参与安装和...

    小手冰凉
  • EMR(弹性MapReduce)入门之kafka实战(十五)

    Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以...

    小司机带你入门EMR

扫码关注云+社区

领取腾讯云代金券