RxSwift 基础

在 iOS 开发过程当中,咱们几乎无时无刻都要面对异步事件的处理。例如,按键点击、数据保存、、音频后台播放、交互动画展现。这些事件并不具有特定时序性,甚至它们可能同时发生。html

虽然 Apple 提供了通知、代理、GCD、闭包等异步机制,可是这些机制缺少一个统一的抽象表述。另外,这些机制在处理共享的可变数据或状态时不够清晰简练。固然,这并非说编写优雅的异步代码不现实。毕竟与其余平台相比 iOS 的异步机制仍是很强大的。git

幸运的是,咱们可以经过 RxSwift 优雅的处理异步代码。github

至于 RxSwift 的优点以及为何要使用它,详见文档。这里就不废话了。编程

RxSwift 简介

其实响应式编程并非一个什么新的概念,只不过是最近几年受到了开发者更多的关注。它最先由巨硬提出,主要的目的是为了应对复杂的 UI 异步事件和应用实时响应。社区中也已经有了各类语言版本的响应式编程实现,包括:RxJS、RxKotlin、Rx.NET、RxScala、RxSwift。这些类库仅仅只是实现方式存在差别,因此开发者在讨论应用逻辑时不会存在沟通障碍。swift

RxSwift 做为 Swift 语言的响应式编程实现,它在传统的命令式编程和纯函数式编程中找到了一个很好的平衡点。经过使用不可变代码定义异步处理输入,RxSwift 以一种肯定可组合的形式对事件作出响应。bash

总的来讲,RxSwift 有三个主要构成部分:ObservableOperatorScheduler 。下面咱们就来一一介绍。服务器

Observable

Observable 类能够说是 RxSwift 整个框架的基石。它能异步的触发一系列事件流并携带不可更改的状态变量。简单来讲就是:它能让某个类的实例在一段时间内实现对另外一个实例对象值的观察。例如:观察者能够捕获对全部可观察对象触发的事件,从而实现 UI 的实时更新或者是数据的实时处理。 网络

其中 Observable 类遵循了 ObservableType 协议。另外,Observable 对象所能触发的事件只有如下三种: 闭包

  1. next 事件:该事件在触发时会将可观察对象的最新值传递给观察者。
  2. completed 事件:该事件意味着可观察对象的生命周期正常结束不会在继续触发事件。
  3. error 事件:该事件代表可观察对象出现了错误致使生命周期异常终止。

对于一个可观察的整型变量来讲,异步环境下它所触发的事件能够在时间线上被描绘成这样一个事件序列:架构

2017-09-02-01
2017-09-02-01

另外,咱们能够对这三类事件进行组合从而实现更为复杂的业务逻辑。与此同时,咱们还可使用该机制轻松实现代码解耦和多个对象间数据传递,无需编写代理或者闭包代码。

2017-09-02-02
2017-09-02-02

这里,咱们还有一点值得注意。那就是可观察序列其实有两种类型。

有限观察序列( Finite observable sequences )

该序列是指那些最后会以 completed 或者 error 事件终极生命周期的可观察对象。最典型的例子就是,经过 API 进行网络请求:

  1. 开始数据请求并准备进行数据接收。
  2. 接收到服务端响应开始接收数据。
  3. 若是服务器或者网络发生故障则关闭请求并触发错误处理。
  4. 若是一切正常则对请求数据进行处理和分析。

下面是一个文件下载请求的 Rx 范式的代码:

API.download(file: "http://www...")
    .subscribe( onNext: { data in
                        append data to temporary file }, 
                onError: { error in
                        display error to user }, 
                onCompleted: {
                        use downloaded file })复制代码

这段代码中 API.download (file:) 函数会建立一个 Observable 实例对象,而且在整个数据接收过程当中会不断的触发 next 事件。而后,咱们在 next 事件中会将这些片断数据保存到临时文件中。若是此过程出现错误的话,咱们会将错误信息展现给用户。若是一切顺利咱们会将临时文件保存到设备中。最后在下载完成后,咱们能够在 completed 进行下一步的逻辑处理。

无限观察序列( Infinite observable sequences )

与网络任务不一样的是,UI 以及交互事件是无限观察序列。它们并不存在一个明确的生命周期终结点。例如,针对可能的设备方向旋转,咱们须要实时进行布局修改。而设备的方向旋转自己是随机发生的而且与应用自己具备一样的生命周期。所以 Rx 也须要一种机制支持这种无限观察序列。

针对这种状况,在 RxSwift 中咱们能够经过如下代码来应对:

UIDevice.rx.orientation.subscribe(onNext: { current in 
    switch current { 
        case .landscape:
            re-arrange UI for landscape 
        case .portrait:
            re-arrange UI for portrait 
    } 
})复制代码

操做符

ObservableType 以及 Observable 类的实现中都包含大量的异步处理方法,这些方法也被称为操做符。因为这些操做符只是进行异步输入处理并产生对应输出,因此它并不会对应用产生多余的反作用。另外,由于操做符之间的高度解耦因此咱们很容易对它进行组合以期实现复杂的功能。

例如,对于上面的设备方向旋转,咱们能够对全部的状况进行过滤而后对部分值进行进一步处理。

UIDevice.rx.orientation
    .filter { value in
        return value != .landscape 
    } 
    .map { _ in
        return "Portrait is the best!" 
    } 
    .subscribe( onNext: { string in 
        showAlert(text: string) 
    })复制代码

上面的代码中,咱们首先会将全部 .landscape 方向过滤掉不作任何处理。而后,咱们再将剩下的 portrait 转化为字符串 Portrait is the best! 。整个处理流程大体以下:

2017-09-02-03
2017-09-02-03

这种函数式的操做符让咱们能够灵活的组合出更强大的功能。

Scheduler

Schedulers 是一个与 GCD 相对应的概念,只不过前者使用起来更为方便。RxSwift 中预约义的 Schedulers 足够开发者应对绝大多数的编程场景。

例如,咱们可使用串型序列 SerialDispatchQueueScheduler 来处理 next 事件,经过 ConcurrentDispatchQueueScheduler 运行并行文件下载任务,经过 OperationQueueScheduler 运行一个 NSOperationQueue 操做队列。甚至你能够在同一个观察对象的不一样任务中使用不一样的 Schedulers 类型,以下图:

2017-09-02-04
2017-09-02-04

咱们将左侧的任务用不一样的颜色加以区分,而后在右侧任务被拆分为不一样的步骤而且放在不一样 Schedulers 中。例如,network subscription 任务就被拆分为三个步骤并依次放入了 Custom NSOperation SchedulerBackground Concurrent SchedulerMain Thred Serial Scheduler

补充

值得注意的是, RxSwift 并无对客户端的应用架构做出硬性规定。这意味着,咱们能够在已有项目中引入 RxSwift 进行响应式编程实践。固然已有框架中一定存在一个最适合 RxSwift 的,而它就是 MVVM。由于在 MVVM 中咱们能够将 VM 中的部分属性直接与 UI 进行绑定。

2017-09-02-05
2017-09-02-05

另外,对于 iOS 编程来讲仅仅有 RxSwift 是远远不够的。RxSwift 只是 Swift 语言的响应式实现,咱们还须要一种 Cocoa 层面的实现。好在这里存在 RxCocoa 做为 UIKit 的响应式补充。前面设备方向代码 UIDevice.rx.orientation 就是 RxCocoa 的应用 。

总结

做为系列开篇,本文介绍了 RxSwift 的一些基本理念和构成,更多相关的内容将会在后面带来。

原文地址

相关文章
相关标签/搜索