iOS理解函数响应式编程RxSwift

472 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

函数响应式编程

函数式编程

Functional Programming

1、常见解释

函数式编程 是一种思维模式,一种编程思想,一种编程方式,一种编程范式

//常见的函数式编程 masonry,snapkit
make.centerY.equalTo(self.view).offset(100);

2、基本特性&优点

允许把函数本身作为参数传入另一个函数,同时还允许返回一个函数

//将数组中,针对>4的数字,+1处理,最后输出所有的偶数
let arr1 = [1,2,3,4,5,6,7,8,9,10]
       for item in arr1 {
           if(item>4){
               let num = item + 1;
               if(num % 2==0){
                   print(num)
               }
           }
       }
​
//函数式编程
arr1.filter{ $0 > 2}
      .filter{ ($0+1) % 2 == 1}
      .forEach { print($0) }
​

2.1优点

  • 函数即不依赖外部的状态也不修改外部的状态:函数调用的结果不依赖调用的时间和空间状态,这样写的代码容易进行推理,不容易出错。这使得单元测试和调试都更容易。
  • 线程安全:函数式编程可以帮我们解决这一痛点,每一个纯函数都是线程安全
  • 代码层次非常清晰、代码可读性高、代码复用性高
  • 代码简洁,直接面向开发需求

总结:1、函数式编程并不会减少我们的代码量,它改变的只是我们书写代码的方式

2、编程方式表达更接近于自然语言,调用表达可直译(对命名准确性要求高),注重结果。

响应式编程

对象对某一数据流变化做出响应的这种编码方式称为响应式,动态感知数据的变化,从化刷新UI界面。

/**
举个栗子,在一般程序开发时
        x= y + z
    赋值之后 y 或者 z 的值变化后,x 的值不会跟着变化. 
*/
如果使用响应式编程,目标就是,如果 y 或者 z 的数值发生变化,x 的数值会同时发生变化
​
如何才能做到及时响应呢? 
一般情况可以对 y 和 z 进行观察,一旦发生变化,及时通知 x 发生变化 
-----> 代理、通知、block 
​

在iOS开发中我们经常会响应一些事件buttontaptextViewnotifactionKVONSTimer等等这些,都需要做响应监听,响应后都需要在对应的响应事件中去做处理。而原生开发中,触发对象与响应方法是分离的,如button的初始化和点击响应方法是分离的,功能代码与逻辑代码分离。

RxSwift简介

基本定义

作为ReactiveX家族之一的RxSwiftGithub截止现在Star:22.3KReactiveX 不仅仅是一个编程接口,它是一种编程思想的突破,它影响了许多其它的程序库和框架以及编程语言。它拓展了观察者模式,使你能够自由组合多个异步事件,而不需要去关心线程同步,线程安全并发数据以及I/O阻塞

Tips:都说Rx的学习成本高,其实不然。api非常精简,使用起来还是比较顺畅。

       //1.创建序列
       Observable<String>.create{(obserber)->Disposable in
          //3.发送型号
           obserber.onNext("发送信号")
           return Disposables.create()
           //2.订阅序列
       }.subscribe(onNext: {
           (msg) in
           print("订阅到:(msg)")
       })
​

核心流程

1、创建序列

rxswift-创建序列.jpg 观察序列 的创建是利用协议拓展功能的create方法实现的,里面创建了一个 AnonymousObservable(匿名可观察序列) 命名还是体现了author的思维 :这个类就是一个内部类,具备一些通用特性(具有自己功能的类才会命名)下面我列举的继承关系

创建序列继承关系.jpg

从上面的图,我们可以清晰的看到的继承关系。这个地方我们需要理解:

  • create 方法的时候创建了一个内部对象 AnonymousObservable

  • AnonymousObservable 保存了外界的闭包

    extension ObservableType {
       // MARK: create
    ​
       /**
        Creates an observable sequence from a specified subscribe method implementation.
    ​
        - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html)
    ​
        - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method.
        - returns: The observable sequence with the specified implementation for the `subscribe` method.
        */
       public static func create(_ subscribe@escaping (AnyObserver<Element>) ->Disposable) -Observable<Element> {
           AnonymousObservable(subscribe)
       }
    }
    
  • AnonymousObservable继承了 Producer 具有非常重要的方法 subscribe

final private class AnonymousObservable<Element>: Producer<Element> {
   typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
​
   let subscribeHandler: SubscribeHandler
​
   init(_ subscribeHandler@escaping SubscribeHandler) {
       self.subscribeHandler = subscribeHandler
   }
​
   override func run<ObserverObserverType>(_ observerObservercancelCancelable) -> (sink: Disposable, subscription: Disposablewhere Observer.Element == Element {
       let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
       let subscription = sink.run(self)
       return (sink: sink, subscription: subscription)
   }
}
​
2、 订阅序列

subscribe 方法的拓展,创建了一个 AnonymousObserver (匿名内部观察者),它这里的初始化是闭包参数,保存了外界的 onNext, onError , onCompleted , onDisposed 的处理回调闭包的调用。

订阅者.jpg AnonymousObserver的继承关系

AnonymousObserver内部观察者继承关系.jpg

  • self.run 这个代码最终由我们生产者 Producer 延伸到我们具体的事务代码 AnonymousObservable.run

    sink.run

  • parent 就是上面传过来的AnonymousObservable对象

    func run(_ parentParent) -> Disposable {
    ​
       return    parent.subscribeHandler(AnyObserver(self))
    ​
     }
    
  • 最终造方法里面,我们创建了一个结构体 AnyObserver 保存了一个信息 AnonymousObservableSink

    public static func create(_ subscribe: **@escaping** (AnyObserver<Element>) ->Disposable) -Observable<Element> {
    ​
    return    AnonymousObservable(subscribe)
    ​
     }
    
3、发送信号

obserber.onNext("msg") 的本质是: AnyObserver.onNext("msg")

let observer = AnonymousObserver<Element> { event in
               
               #if DEBUG
                   synchronizationTracker.register(synchronizationErrorMessage:.default)
                   defer { synchronizationTracker.unregister() }
               #endif
               
               switch event {
               case .next(let value):
                   onNext?(value)
               case .error(let error):
                   if let onError = onError {
                       onError(error)
                   }
                   else {
                       Hooks.defaultErrorHandler(callStack, error)
                   }
                   disposable.dispose()
               case .completed:
                   onCompleted?()
                   disposable.dispose()
               }
           }
​

总结

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

RxSwift一定程度上弥补Swift的灵活性

  • RxSwift使得代码复用性较强,减少代码量
  • RxSwift因为声明都是不可变更,增加代码可读性
  • RxSwift使得更易于理解业务代码,抽象异步编程,统一代码风格
  • RxSwift使得代码更易于编写集成单元测试,增加代码稳定性