RxSwift 源码学习之just

1,583 阅读5分钟

项目中一直使用着 RxSwift,现在也只是停留在使用的阶段,最近利用闲暇的时间拜读了一下 RxSwift 的源码。

介绍

RxSwift 是一个可以帮助我们简化异步编程的框架,它是 ReactiveX(简写:Rx) 的 Swift 版本。 RxSwift 拓展了观察者模式,它能帮你自由组合多个异步事件,而不需要去关心线程,同步,线程安全,并发数据以及I/O阻塞。

RxSwift 属于函数响应式编程。它是通过构建函数操作数据序列,然后对这些序列做出响应的编程方式。它结合了函数式编程以及响应式编程。

开篇

let observable =  Observable.just("hello")

observable.subscribe(onNext: { (str) in

    }, onError: { (error) in

    }, onCompleted: {
        //finished
    }).disposed(by: self.disposeBag)

我的记录就从上面这个简单的 RxSwift 使用示例开始,一步步去探寻 RxSwift 源码。

源码阅读

Observable

Observable 定义:

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

    /// Optimizations for map operator
    internal func composeMap<Result>(_ transform: @escaping (Element) throws -> Result) -> Observable<Result> {
        return _map(source: self, transform: transform)
    }
}
  • init 方法被 internal 修饰,模块外部不可见。主要是为了监测 Rx 中的资源分配。
  • 关键方法 public func subscribe<O: ObserverType>(_ observer: O) 实现中直接抛出异常;rxAbstractMethod 是对 fatalError的封装。

just 函数

public static func just(_ element: Element) -> Observable<Element> {
    return Just(element: element)
}

Observable 的实例方法不可用,但是 Rx 中为我们扩展了许多类方法用于构造 Observable 实例。本文就以 just 方法为例。

调用 just 函数时,传入了一个数据,这里利用泛型,我们可以传入任何我们需要的数据。并且返回一个 Observable 实例对象。 函数内部调用了一个私有类 Just:

final private class Just<Element>: Producer<Element> {
    private let _element: Element
    
    init(element: Element) {
        self._element = element
    }
    
    override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        observer.on(.next(self._element))
        observer.on(.completed)
        return Disposables.create()
    }
}

私有类 Just 中持有了我们传入的数据 Element。

那么,后续我们就看看当我们对 Observable 进行订阅时,我们是如何收到消息的。

subscribe 函数

我们利用 subscribe 函数订阅刚才生成的 Observable 实例。我们先来看看 subscribe 函数的实现。

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()
    }
    
    let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
    
    let observer = AnonymousObserver<Element> { event in
        
        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(
        self.asObservable().subscribe(observer),
        disposable
    )
}

可以看到,函数有四个可选参数:onNext、onError、onCompleted、onDisposed。

并且在函数内部生成了一个 observer 对象,并且又利用 create 函数创建了一个 Observable 实例供外界使用。并且调用了 subscribe 方法将 observer 传入。

此时,会来到前面我们生成 Observable 实例时提到的的私有类 Just 中:

override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
    observer.on(.next(self._element))
    observer.on(.completed)
    return Disposables.create()
}

这里出现了一个在 RxSwift 中经常出现的概念 Event,并且这个 Event 现在持有了 Just 中我们生成 Observable 时传入的 Element 对象:

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
}

这里的 observer 就是在最开始时的 subscribe 函数中生成的。接下来,我们来看看这个生成的 observer 到底是何方神圣吧?

observer

let observer = AnonymousObserver<Element> { event in
    
    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()
    }
}

这是 subscribe 时,生成 observer 的代码,我们可以看到这是一个 AnonymousObserver 的对象:

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>) {
        return self._eventHandler(event)
    }
}

我们可以看到这里持有了创建时传入的闭包,并且在 onCore 方法调用时,执行了这个闭包。我们继续往上找,我们来到 ObserverBase 中:

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

    func dispose() {
        fetchOr(self._isStopped, 1)
    }
}

这里面我们终于找到了处理私有类 Just 内 subscribe 函数中 observer.on(event) 的地方了,这里判断了 event 的类型,并调用了 onCore(event) 方法。下面我们就回到了上面 AnonymousObserver 中的 onCore(event) 方法,并最终执行了创建 observer 时创建的闭包。

我们再回头看一下生成 observer 时的代码。在传入的闭包中,处理了 event,根据 event 的不同传入对应的数据。我们这里关注 next 函数,这里最终将我们生成 Observable 时传入的 Element 传给了调用 subscribe 时传入的 onNext 闭包。

这样,当利用 just 函数生成一个 Observable 对象,并且订阅值之后的相应处理也就完成了。

总结

这篇文章追寻一个简单的 just 函数,探寻了 RxSwift 的源码,我们可以看到 RxSwift 将我们的处理事件的逻辑封装成闭包,保存在合适的地方,并在需要处理相应事件时,将对应处理的闭包取出来处理。这个处理事件的方式在异步编程的优势就非常明显了。

RxSwift 的源码真的是非常简洁明了,在阅读源码的过程中不仅可以让自己在使用时更加得心应手,也能学习到大牛的一些编程思想。