RxSwift的简单入门

351 阅读9分钟

RxSwift的简单入门

《零基础入门RxSwift》

RxSwift核心有三个概念:生产者(发布者)、订阅者、销毁者。简单理解就是生产者负责产生信号,订阅者订阅信号,销毁者负责生命周期的管理。

let ob = Observable<String>.create { observer in // 创建信号
    observer.onNext("a")
    observer.onNext("b")
    observer.onNext("c")
    observer.onCompleted()
    return Disposables.create()
}

let _ = ob.subscribe { event in // 订阅信号
   switch event {
   case .next(let element):
       print(element)
   case .error(let error):
       print(error)
   case .completed:
       print("completed")
   }
}.disposed(by: disposeBag)

上述2段代码其实就是RxSwift的基本使用,创建生产者和订阅他的值。开发者需要关注的其实就是2个闭包:

  • 生产闭包:我们在生产者的create闭包里面去不断的生产数据。例如网络请求回来后的数据,可以next下去。
  • 订阅闭包:订阅数据,当生产的数据执行next时,下方的订阅的闭包就会收到next的内容。

最后的disposebag,也就是垃圾袋主要是为了管理整个数据流的生命周期,通过它数据流就会被释放和销毁。

恭喜你,看到这里《零基础入门RxSwift》已经学习完毕,再见啦!88~

《RxSwift从入门到精通》

当了解了RxSwift的用法后,2个问题一直困扰着我。

  • 生产闭包谁在调用?
  • 订阅闭包谁在调用?

生产闭包的调用

我们通过Observable<String>.create来创建生产者,并且把生产闭包作为他的第一个参数来传递。那我们首先需要了解2个东西,什么是Observable以及他的create方法

Observable

public class Observable<Element> : ObservableType {
    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        rxAbstractMethod()
    }
    public func asObservable() -> Observable<Element> { self }
}

Observable类看上去非常的寒酸,一个subscribe方法,是因为实现了协议ObservableType必须得整一个。内部调用了一个有着Abstract关键字的方法,不用看了,抽象方法都不是给自己用的,给子类重写的。另一个asObservable方法,很遗憾这玩意也不是他自己独有的,是因为协议ObservableType还遵循了一个ObservableConvertibleType协议带来的方法。至此结束,结论:Observable啥也没有,研究错对象了,重头戏还得是他的儿子们

create

create方法就比Observable有点意思,他其实不在Observable内部,而是放在了ObservableType+Extensions.swift中。举个例子:我整了个protocol然后写了个他的extensionprotocol定义的方法直接实现了。谁要实现我这个协议,里面定义的方法都不用再写一遍了,捡现成的。我们在观察RxSwift的源码过程中会发现,在他内部的实现中大量的采用了这种方式。

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

create方法的内部返回的是一个叫做AnonymousObservable的类。懂了,Observerable就是个马甲,真正返回的是这个。

AnonymousObservable是个啥
graph LR
A(AnonymousObservable)-->B(Producter)-->C(Observable)-.protocol.->D(ObservableType)-.protocol.->E(ObservableConvertibleType)

他是Observable的子类,准确来说是孙子。继承链大致就是上面这个情况。内部函数很简单,一个subscribeHandler用来保存外部传递进来的生产闭包。一个打了override标签不知道干啥的run函数。

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

所以要找到生产闭包是什么时候被调用的,思路其实很清晰。就看谁在调用self.subscribeHandler

然后实际它调用的时机并非在创建时,而是在被订阅时。让我们先看一下我们是如何订阅的,let _ = ob.subscribe(xxx)。首先搞懂几个问题,ob是谁?他是我们刚刚返回的AnonymousObservable对象。他有subscribe方法吗?有的,因为它实现了ObservableType协议,而ObservableType的extension有subscribe方法的实现。

public func subscribe(_ on: @escaping (Event<Element>) -> Void) -> Disposable {
    let observer = AnonymousObserver { e in
        on(e)
    }
    return self.asObservable().subscribe(observer)
}

subscribe方法的参数是什么?就是我们的订阅闭包。OK,紧跟着订阅闭包,就能找到它触发的时机。

它返回一个Disposable函数,但最重要的步骤则是他在subscribe函数内部创建了一个叫做AnonymousObserver的家伙。

AnonymousObservable vs AnonymousObserver

一个结尾是able代表生产者,一个结尾是er代表订阅者,别搞混啦。可以看到我们外部的订阅闭包被AnonymousObserver初始化的闭包持有了,而我们的生产闭包还在AnonymousObservable.subscribeHandler内部存着。

再回到subscribe函数,最精彩的部分来啦。人类的一小步,宇宙的一大步。此时此刻,他们在self.asObservable().subscribe(observer)这一行代码处交汇了。你说啥?只看到了observer没看到observable?睁开眼睛,想想self是谁? Oh~ 他就是AnonymousObservable

subscribe函数

AnonymousObservable对象调用了asObservable(),这个是干啥的?

其实上文介绍过他,来自于ObservableConvertibleType协议。代码就一行public func asObservable() -> Observable<Element> { self }实际上啥都没干,直接返回self。但是此时的self的类型变成了Observable,我的理解这里就是一个多态的用法。父类指针指向子类对象,模糊掉具体的实现类。

既然asObservable()啥都没干,那我们真正的重点其实在subscribe(observer)函数。这个函数我们上文也介绍过,他声明在ObservableType协议内。并且有提到这个方法的真正的实现应该在Observable的子类中。

AnonymousObservable对象(也就是self),在调用asObservable()后,其实啥都没干。接着继续调用subscribe方法。而他本身的类并没有实现这玩意,那按照上方的继承链,我们往上找。这个时候一个新的类出现在我们的视野里,Producer

class Producer<Element>: Observable<Element> {
		...
    override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
          ...
        }
        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
            }
        }
    }

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

Producer在subscribe做了啥?拨开线程(thread)相关的代码,和我们暂时不关心的销毁管理者dispose代码。核心代码其实就一句let sinkAndSubscription = self.run(observer, cancel: disposer)。恰好run方法下面就有定义,rxAbstractMethod()。OK,又是Abstract(抽象方法),不用看了,直接看子类吧。

故事又回到了原点,回到了我们的AnonymousObservable类。在上文中我们有提到,在这个类里面有一个打了override标签不知道干啥的run函数,这下我们知道他是谁调用的了。当AnonymousObservable调用了subscribe函数时,他的内部会触发run方法。

run函数
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)

让我们看看run函数内部干了啥,创建了一个AnonymousObservableSink对象,然后出发了对象的run方法,并且把self传递了进去。

让我们再来整理一下思路:

  1. 此时是谁在调用这个函数,或者的self是谁?是AnonymousObservable,也是我们生产闭包的持有者
  2. AnonymousObservableSink在创建时传入的2个参数是谁?
    1. observer: AnonymousObserver类型,我们在subscribe函数创建的那个,他的闭包里面持有了我们的订阅闭包
    2. cancel: Disposable 和取消销毁有关,本次不探讨
  3. sink.run(self), self就是AnonymousObservable

天时地利人和,sink对象内部集齐了所有的上下文环境,有生产者Observable,有订阅者Observer,还有销毁者disposer。看看sink的run函数会干啥吧~

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

首先看run函数的参数parent: Parent,这个是啥?噢,sink.run(self), self就是AnonymousObservable

graph LR
A(parent)--就是-->B(AnonymousObservable)
C(parent.subscribeHandler)--就是-->D(AnonymousObservable.subscribeHandler)--就是-->E(生产闭包)
parent.subscribeHandler(AnyObserver(self))

这就是调用生产闭包的时机。终于,我们找到了第一个问题的答案。

graph TB
A(外界调用subscribe函数,参数是闭包)-->B(AnonymousObservable.subscribe函数,参数是observer)-->C(Producer.subscribe)-->D(AnonymousObservable.run)-->E(AnonymousObservableSink.run)-->F(parent.subscribeHandler被调用,参数是AnyObserver)-->G(生产闭包)

订阅闭包的调用

AnyObserver

上文我们找到了Observable.create的闭包调用时机,那这个闭包参数observer是谁呢?为什么他onNext时,我的订阅闭包能收得到消息呢?答案还是在subscribeHandler(AnyObserver(self))。

AnyObserver(self)就是我们在create闭包中使用的observer对象。

public struct AnyObserver<Element> : ObserverType {
    public typealias EventHandler = (Event<Element>) -> Void
    private let observer: EventHandler
    ...
    public init<Observer: ObserverType>(_ observer: Observer) where Observer.Element == Element {
        self.observer = observer.on
    }
   
    public func on(_ event: Event<Element>) {
        self.observer(event)
    }

    public func asObserver() -> AnyObserver<Element> {
        self
    }
}

他是一个结构体,初始化时我们传递进来的observer又是谁呢?是AnonymousObservableSink,skin可是拥有生产闭包、订阅闭包等所有的上下文哦。

在初始化init函数中,有一个这个动作self.observer = observer.on,简单点就是把Sink的on方法给了self.observer。而AnyObserver.on方法被触发时,它内部调用到了self.observer。因为这次的赋值,最终会指向了AnonymousObservableSink的on方法。

那什么时候AnyObserver.on方法会被触发呢?他其实就是我们在create闭包里面写的onNext、onError。

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

当我们在create闭包内,调用observer.onNext(element)方法时。他其实就是AnyObserver.on(.next(element))被触发了。

接着Sink的on函数被触发,让我们再来看看Skin类的定义。

final private class AnonymousObservableSink<Observer: ObserverType>: Sink<Observer>, ObserverType {
    typealias Element = Observer.Element 
    typealias Parent = AnonymousObservable<Element>
    // state
    private let isStopped = AtomicInt(0)

    override init(observer: Observer, cancel: Cancelable) {
        super.init(observer: observer, cancel: cancel)
    }

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

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

我们之前介绍的是它的run函数,现在来研究他的on函数。我们在create闭包中发起onNext,Skin的on函数会收到调用,然后走入他的事件转发流程self.forwardOn(event)

  final func forwardOn(_ event: Event<Observer.Element>) {
      if isFlagSet(self.disposed, 1) {
          return
      }
      self.observer.on(event)
  }

forwardOn函数内,值得我们注意的只有一行代码self.observer.on(event)。但此时我们需要思考几个问题:

  • self是谁?
  • observer是谁?
  • on是什么?
  • event是什么?

self是AnonymousObservableSink对象,他的observer其实就是AnonymousObserver对象。对,就是那个拥有订阅闭包的家伙。on函数也就是Observer对象的函数。而event最简单,就是我们在create闭包中触发的事件

AnonymousObserver

graph LR
A(AnonymousObserver)-->B(ObserverBase)-.protocol.->C(ObserverType)-->E(func on函数)
B-.protocol.->D(Disposable)
F(AnyObserver)-.protocol.->C
final class AnonymousObserver<Element>: ObserverBase<Element> {
    typealias EventHandler = (Event<Element>) -> Void
    private let eventHandler : EventHandler
    init(_ eventHandler: @escaping EventHandler) {
        self.eventHandler = eventHandler
    }

    override func onCore(_ event: Event<Element>) {
        self.eventHandler(event)
    }
}

AnonymousObserver似乎没有on函数的实现,但是有一个override的onCore函数。而我们顺着继承链能在ObserverBase类中找到on的真正实现。

class ObserverBase<Element> : Disposable, ObserverType {
    private let isStopped = AtomicInt(0)

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

    func onCore(_ event: Event<Element>) {
        rxAbstractMethod()
    }
}

又是一次消息转发,on函数最终指向了onCore。而onCore在AnonymousObserver中的实现则是调用他持有的闭包self.eventHandler(event)。eventHandler是啥?还记得在subscribe订阅方法内,创建AnonymousObserver对象时传递的闭包吗?这个闭包持有了我们一直心心念念的订阅闭包。

public func subscribe(_ on: @escaping (Event<Element>) -> Void) -> Disposable {
    let observer = AnonymousObserver { e in
        on(e)
    }
    return self.asObservable().subscribe(observer)
}

当AnonymousObserver的闭包在onCore中被调用时,事件层层传递到了我们最外层的业务代码订阅闭包。

综上,我们得到了最后一个问题的解释,这里就是订阅闭包被调用的时机。

graph LR
A(AnyObserver)--func onNext-->B(AnonymousObservableSink)--self.observer-->C(AnonymousObserver)--OnCore-->D(订阅闭包)