当前位置: 首页 > 工具软件 > RxSwift > 使用案例 >

RxSwift学习(一) --- RxSwift介绍

齐承泽
2023-12-01

函数响应式式编程(FRP)

函数式编程(FP)

函数式编程就是一种抽象程度很高的编程范式,它将计算机运算看做是数学中函数的计算,而纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用

简单来说: 将函数作为一个单元来处理逻辑,给定一个输入值,就会有对应的一个输出值。函数还可以作为参数和返回值。这就是函数编程。

函数表达式: y = f(x) —> x = f(x) —> y = f(f(x))

函数编程的特性

  • 闭包: 一种特殊的函数,绑定了函数内部引用的所有变量,把它引用的东西都放在一个上下文中“包”了起来
  • 高阶函数: 把函数作为参数或者返回值的函数
  • 匿名函数: 在传入函数时,有些时候,不需要显式地定义函数,可以直接传入匿名函数。
  • 柯里化: 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术

优点

  • 惰性
  • 递归
响应式编程 (RP)

响应式编程是一种从数据流和变化出发的解决问题的模式。 响应式编程,本质上是对数据流或某种变化所作出的反应,但是这个变化什么时候发生是未知的,所以是基于异步、回调的方式在处理问题。

通俗来讲:A赋值给BB发生变化的时候A也会跟着发生变化,这就是响应式编程。

响应式编程

  • 数据流: 一个流就是一串事件发生的时间的值的序列。这里面至少有三要素:数据报错完成.
  • 变化: 信号变化回调
函数响应式编程(FRP)

函数响应式编程:说白了就是函数式和响应式的结合.

RxSwift 介绍

RxSwift: 是 Rx 为 Swift 语言开发的一门函数响应式编程语言, 它可以代替iOS系统的 Target Action / 代理 / 闭包 / 通知 / KVO,同时还提供网络、数据绑定、UI事件处理、UI的展示和更新、多线程……

在RxSwift中,所有异步操作(事件)和数据流均被抽象为可观察序列的概念
RxSwift的主要流程: 创建序列 --> 订阅序列 --> 发送信号 --> 信号接收

一、RxSwift 配置

  1. 使用RxSwift需要导入RxSwiftRxCocoa 这两个库,缺一不可。这两个库的主要作用是:
  • RxSwift:它只是基于 Swift 语言的Rx 标准实现接口库,所以 RxSwift 里不包含任何 Cocoa 或者 UI 方面的类
  • RxCocoa:是基于 RxSwift 针对于 iOS 开发的一个库,它通过 Extension 的方法给原生的比如 UI 控件添加了 Rx 的特性,使得我们更容易订阅和响应这些控件的事件。
  1. 再使用RxSwift的地方import这个两个库就行
import RxSwift
import RxCocoa

二、Observable (创建、订阅、销毁)

1、Observable
  • Observable<T>: 观察序列

1、Observable 这个类就是 Rx 框架的基础,我们可以称它为可观察序列。它的作用就是可以异步地产生一系列的 Event(事件),即一个 Observable 对象会随着时间推移不定期地发出 event(element : T) 这样一个东西。
2、这些 Event 还可以携带数据,它的泛型 就是用来指定这个 Event 携带的数据的类型。
3、有了可观察序列,我们还需要有一个 Observer(订阅者)来订阅它,这样这个订阅者才能收到 Observable 不时发出的 Event。

  • Enevt: 事件。
    Observable可以发出三种不同的事件:nexterrorcompleted
public enum Event<Element> {
    /// Next element is produced.
    case next(Element)

    /// Sequence terminated with an error.
    case error(Swift.Error)

    /// Sequence completed successfully.
    case completed
}

1、next: next 事件就是那个可以携带数据 <T> 的事件
2、error: error事件表示一个错误,它可以携带具体的错误内容,一旦 Observable 发出了 error event,则这个 Observable 就等于终止了,以后它再也不会发出 event 事件了
3、completed: completed 事件表示 Observable 发出的事件正常地结束了,一旦 Observable 发出了completed event,则这个 Observable 就等于终止了,以后它再也不会发出 event 事件了

2、Observable 序列的创建

Observable有好多种序列的创建方法,我们这里就解说一种比较常用的create() 序列创建,其他常见的可以参考Observable 常见的序列创建方法

create 序列

  • 该方法接受一个 闭包形式的参数,任务是对每一个过来的订阅进行处理。
  • 下面是一个简单的样例。为方便演示,这里增加了订阅相关代码
  • 这也是序列创建的一般方式,应用非常之多
// 1、创建序列
_ = Observable<String>.create({ (observable) -> Disposable in
            //3、发送信号
            observable.onNext("RxSwift  你好!")
//            observable.onError()  //发送错误信号
//            observable.onCompleted() //发送完成信号
            
            return Disposables.create() // 销毁
           // 2、订阅序列
        }).subscribe(onNext: { (next) in
            NSLog("订阅到--\(next)")
        }, onError: { (error) in
            NSLog("错误--\(error)")
        }, onCompleted: {
            NSLog("完成回调")
        }, onDisposed: {
            NSLog("订释放回调")
        })
3、Observable 订阅

一般我们创建完Observable 序列以后,我们会用subscribe()对其进行订阅,用来接收Observable发出的事件Event .
关于subscribe的订阅有两种方式:

  • subscribe()方法:该方法的 block 的回调参数就是被发出的 event 事件,我们将其直接打印出来。
let observable = Observable<String>.of("Json","XML")

observable.subscribe { (event) in
                    Log("---of----\(event)")
                }.disposed(by: self.disposeBag)

// 打印值
//ofQueue():73->---of----next(Json)
//ofQueue():73->---of----next(XML)
//ofQueue():73->---of----completed

1、初始化 Observable 序列时设置的默认值都按顺序通过 .next事件发送出来
2、next事件送完以后,还会自动发送一个completed事件
3、我们要向获取接收到的元素可以用event.element 去获取

  • subscribe的另一种订阅方法:该方法可以把 event 进行分类,通过不同的 block 回调处理不同类型的 event,同时会把 event 携带的数据直接解包出来作为参数,方便我们使用。
	let observable = Observable<String>.of("Json","XML")
              
     observable.subscribe { (element) in
          print("---of----\(element)")
     } onError: { (error) in
          print(error)
     } onCompleted: {
          print("completed")
     } onDisposed: {
          print("disposed")
     }
     
    // 打印
    //---of----Json
	//---of----XML
	//completed
	//disposed

1、我们通过打印发现这次直接打印的是element,不需要event.element处理了
2、每个回调都独立出来了,我们可以做一些不同的业务需求

4、监听事件的生命周期

关于事件的生命周期,我们可以用doOn来监听,关于doOn:

  • doOn 方法的调用不会影响subscribe的调用
  • doOn 方法会在每一次事件发送前被调用
  • 同时它和 subscribe 一样,可以通过不同的 block 回调处理不同类型的 event

doOn的每个回调都发生在subscribe之前
do(onNext:)方法在 subscribe(onNext:) 前调用
do(onCompleted:) 方法在 subscribe(onCompleted:) 前面调用
do(onDisposed)销毁方法却是在subscribe(onDisposed)后面调用的

let observable = Observable<String>.of("Json","XML")
       
        observable
            .do(onNext: { element in
                print("---do---\(element)" )
            }, onError: { error in
                print("do Error:", error)
            }, onCompleted: {
                print("do Completed")
            }, onDispose: {
                print("do Disposed")
            })
            .subscribe { (element) in
                print("---of---\(element)")
            } onError: { (error) in
                print(error)
            } onCompleted: {
                print("completed")
            } onDisposed: {
                print("disposed")
            }
        打印
       // ---do---Json
       // ---of---Json
       // ---do---XML
       // ---of---XML
       // do Completed
       // completed
        //disposed
       // do Disposed
5、Observable 的销毁(Dispose)

当一个Observable被观察订阅后,就会产生一个Disposable实例,通过这个实例,我们就能进行资源的释放了。
对于RxSwift中资源的释放,也就是解除绑定、释放空间,有两种方法,分别是显式释放隐式释放

  • 显式释放: 也就是dispose(), 可以让我们在代码中直接调用释放方法进行资源的释放
let dispose =  self.TestButton.rx.tap.subscribe({ _ in
            NSLog("点击")
        })
 dispose.dispose()
  • 隐式释放
    隐式释放则通过DisposeBag来进行,它类似于Objective-C ARC中的自动释放池机制.
    DisposeBag对于RxSwift就像自动释放池一样,我们把资源添加到DisposeBag中,让资源随着DisposeBag一起释放。

DisposeBag就像个垃圾袋一样,我们把创建的序列放在DisposeBag这个垃圾袋中,他会在合适的时候帮我们释放资源。

// 可以写成全局的
static var disposeBag = DisposeBag()

let observable = Observable<String>.of("Json","XML")
    observable
            .subscribe { (event) in
                    Log("---of----\(event)")
            }.disposed(by: self.disposeBag)
 类似资料: