RxSwift 第一章 核心流程

注: 本系列所有代码基于RxSwift v6.5.0

前言

在这里插入图片描述

作为本系列的开篇,有必要介绍下RxSwift

RxSwiftSwift函数响应式编程的一个开源库,由GithubReactiveX组织开发、维护。RxSwift的目的是让数据/事件流和异步任务能够更方便的序列化处理,能够使用Swift进行响应式编程。

好的,以上是官方解释,下面从开发角度诠释下这个问题:

  1. 易复合,比如将各种UI控件的响应事件以闭包的形式整合到创建代码块里,而不是单独调用方法。既方便代码的维护,又可以直接获取目标元素,比如获取当前响应的Button
  2. 风格统一,当我们进行多人开发时候。统一风格的代码会让我们少很多烦恼。对于代码维护、Review都是最好的选择。
  3. Rx能够完美的支持单元测试,无论你的项目是否需要这么做。但是,当你需要时候,它就在那里。
  4. 对于基于MVVM架构的项目来说,进行双向绑定是一个很繁琐的问题,而Rx能够完美的解决这个问题,可以通过管道化的方案,直接进行数据和组件的绑定。

核心流程

好的,进入正题。RxSwift本质上就是信号的产生、订阅、发送跟销毁。核心逻辑就是产生、订阅、发送三步曲:
1、创建可观察序列(信号)
2、订阅信号
3、发送信号

看代码:

  //  1. 创建可观察序列
  let ob = Observable<Any>.create { observer in
        // 3. 发送信号
        observer.onNext("test")
        return Disposables.create()
    }
   // 2. 订阅信号
   let _ = ob.subscribe(onNext: { str in
        print(str)
    }).disposed(by: disposeBag)
    

以上代码就实现了信号的创建、订阅、发送的整个过程,有熟悉RAC的读者就会一眼看出,这不就是RACSignal的执行流程么。是的,在设计上,它们是一致的。都完成了管道包装到信号发送的过程。接下来逐步分析下该过程在Rx内部是怎么实现的。

创建可观察序列(信号)

Observablecreate 方法实质上是调用了Create文件(RxSwift包里的文件名,方便读者查找)里的create方法:

public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> {
        AnonymousObservable(subscribe)
    }

实质上就是调用了Create文件里的AnonymousObservable类的构造方法,这个类持有一个subscribeHandler 的逃逸闭包,正是我们上边传入的subscribe,即发送信号的闭包。

final private class AnonymousObservable<Element>: Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
     // 发送信号的闭包
    let subscribeHandler: SubscribeHandler
     
    init(_ subscribeHandler: @escaping SubscribeHandler) {
        self.subscribeHandler = subscribeHandler
    }
    ...
}

此时,我们已经完成了创建的过程,只是将发送信号的闭包保存在内部的Observable对象里。

订阅信号

由上文可观察到订阅信号的实质是调用了obsubscribe方法,这个方法在ObservableType+Extensions文件里:

  public func subscribe(
        onNext: ((Element) -> Void)? = nil,
        onError: ((Swift.Error) -> Void)? = nil,
        onCompleted: (() -> Void)? = nil,
        onDisposed: (() -> Void)? = nil
    ) -> Disposable {

            let disposable: Disposable
            
            if let disposed = onDisposed {
                disposable = Disposables.create(with: disposed)
            }
            else {
                disposable = Disposables.create()
            }
            
            #if DEBUG
                let synchronizationTracker = SynchronizationTracker()
            #endif
            
            let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
            //  1、创建observer对象
            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()
                }
            }
            return Disposables.create(
                // 2、 调用ob对象的subscribe。
                self.asObservable().subscribe(observer),
                disposable
            )
    }

上边的代码主要做了两件事情:

  1. 创建observer对象。
    这里的observer对象要区别于上文的observable(观察者和被观察者)。 AnonymousObserver类以尾随闭包的形式被创建为observer。观察下其代码:
final class AnonymousObserver<Element>: ObserverBase<Element> {
    typealias EventHandler = (Event<Element>) -> Void
    
    private let eventHandler : EventHandler
    
    init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self.eventHandler = eventHandler
    }

    override func onCore(_ event: Event<Element>) {
        self.eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}

其构造函数将传入的内容保存为eventHandler存储在该对象里。创建observer对象里进行了代码转换,这里先不做解析,留作下文说明。

  1. 调用ob对象的subscribe
    当去AnonymousObservable类查找时候,并没有发现这个方法,通过继承关系,发现实质上是调用了其父类Producer(在Producer文件中)的subscribe方法。顾名思义,这正是生产者消费者模式的一种体现。父类负责生产,交由子类消费。看具体代码:
  override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            
            let disposer = SinkDisposer()
            // 1. 具体调用
            let sinkAndSubscription = self.run(observer, cancel: disposer)
            disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

            return disposer
        }
        else {
            return CurrentThreadScheduler.instance.schedule(()) { _ in
                let disposer = SinkDisposer()
                let sinkAndSubscription = self.run(observer, cancel: disposer)
                disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

                return disposer
            }
        }
    }

可以看到注释1的地方就是方法的具体流向,即调用了其run方法,虽然Producer中也标明了次方法。但在AnonymousObservable类里重写了该方法,导致真正的调用会在create文件中AnonymousObservable类中进行,此时看到这个类好熟悉,不就是创建信号时候调用的类么?

 override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }

run方法通过一个AnonymousObservableSink的下沉类,调用run(self)。观察这个下沉类的run方法:

 func run(_ parent: Parent) -> Disposable {
        parent.subscribeHandler(AnyObserver(self))
  }

而这个parent只是AnonymousObservable的别名而已:

 typealias Parent = AnonymousObservable<Element>

run(self)就是调用了AnonymousObservable对象的subscribeHandler,也就是创建信号时期传递的发送信号的闭包,此时,也就完成了信号的订阅工作。

发送信号

在上文中,在订阅信号的时候,最终就会执行发送信号的闭包。所以在发送信号的过程中,仅仅需要关注发送的信号是如何回调到订阅时期的 onNext、onError、onCompleted这些方法里即可。

发送信号的过程,以上文中的 observer.onNext("text")为例。根据ObserverType文件中的代码:

    public func onNext(_ element: Element) {
        self.on(.next(element))
    }
    public func onCompleted() {
        self.on(.completed)
    }
   
    public func onError(_ error: Swift.Error) {
        self.on(.error(error))
    }

可知,其实质是调用了相应的on方法,传入枚举值。对于observer来说,AnonymousObserver并没有直接重写该方法,而是放在其父类ObserverBase中重写了该方法:

   func on(_ event: Event<Element>) {
        switch event {
        case .next:
            if load(self.isStopped) == 0 {
                self.onCore(event)
            }
        case .error, .completed:
            if fetchOr(self.isStopped, 1) == 0 {
                self.onCore(event)
            }
        }
    }

这样转化的实质会调用到onCore方法,onCore方法也就是在AnonymousObserver中具体执行的方法:

final class AnonymousObserver<Element>: ObserverBase<Element> {
    typealias EventHandler = (Event<Element>) -> Void
    
    private let eventHandler : EventHandler
    
    init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self.eventHandler = eventHandler
    }
     // 通过event, 执行构造函数传递过来的闭包 
    override func onCore(_ event: Event<Element>) {
        self.eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}

此时,拉回我们的视角,还记得上文我们在创建observer对象的时候,没有详细分解其代码,此时再来看:

   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()
                }
            }

显然, self.onCore(event)observer的构建闭包里执行,比如next最终会调用到 onNext?(value),这里的onNext不正是订阅信号传递进来的闭包,执行这个方法,在订阅里边就得到了回调。

小结

总体原则遵守创建、订阅、发送、回调。通过继承关系实现方法的相互调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一生随愿为剑客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值