RXSwift - 你觉着 just 很 easy?


就这么件简单大的一句话, 调用了好多个类、好多个方法,根本和它娇小的身躯根本不成正比呀。


_ = Observable.just("1").subscribe(onNext: { (str) in
         print(str)
})

Just 代码调用逻辑是什么?

一、从 Observable 说起

  • Observable 是遵循了 ObservableType 协议的类,而 ObervableType 总结的来说实现的是 subscribe 协议。
  • .just("1"),其实是一个 ObervableType 协议的扩展方法, 并不是惯性以为的 Just 类的方法。
    /**
     Returns an observable sequence that contains a single element.

     - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html)

     - parameter element: Single element in the resulting observable sequence.
     - returns: An observable sequence containing the single specified element.
     */
    public static func just(_ element: Element) -> Observable<Element> {
        return Just(element: element)
    }
  • 在 just 方法中调用的 Just(element: element), 才是进入 正经的 Just。 当然进去 Just 最先干的还是 init,Just -> Producer -> Observable 依次调用init 方法,但是 只有 Just 自己的init 干了正事, 把 element 存了起来。
// Just
    init(element: Element) {
        self._element = element
    }
// Producer
    override init() {
        super.init()
    }
// Observable 
    init() {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
    }

二、 接下来才是各种花里胡哨方法跳转:

问:首先来想想 subscribe 是谁实现的方法?
答:因为just("1") 毕竟返回的是 Just 类呀!所以他后面的 subscribe 是Just 的。如果你和我想的一样,恭喜你 你和我入坑的姿势是一样的,嘿嘿 真爽。

  • subscribe 是 ObservableType 协议的 extension 实现!!!,但是为啥 Just 对象能调用呢? 因为 Just 是继承 Producer , 而 Producer 则是继承了 Observable ,最后就是 Observable 是遵守了 ObservableType 协议 所以 Just 的 对象能调用 subscribe ...... 方法。

2.1、敲重点, 这个 subscribe 是灵魂。

/**
     Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
     
     - parameter onNext: Action to invoke for each element in the observable sequence.
     - parameter onError: Action to invoke upon errored termination of the observable sequence.
     - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
     - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
     gracefully completed, errored, or if the generation is canceled by disposing subscription).
     - returns: Subscription object used to unsubscribe from the observable sequence.
     */
    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() : []
            
            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(
                self.asObservable().subscribe(observer),
                disposable
            )
    }
  • Subscriber 执行到 AnonymousObserver 类的时候 ,就会发现 她是一个 继承自 observerBase 的类, 而且也没什么方法,也很简单的类。其实这是错觉,它才是我们能回调的 起 承上启下的作用的类。

  • 首先在 AnonymousObserver 初始化时会把 闭包 保存成 属性(self._eventHandler(event)),并在 onCore方法 通过闭包(self._eventHandler(event))进行回调 。

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>) {
        return self._eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}

2.2、继续向下执行到 return Disposables.create(self.asObservable().subscribe(observer),disposable)

  • self.asObservable() 这个方法进入的是 Observable (因为 Just 并没有实现 asObservable 所以进入的是 父类的方法),
    public func asObservable() -> Observable<Element> {
        return self
    }
  • subscribe 这个方法进入的就是 Just 自己的 方法了(因为 Just 重写了),.next(self._element).completed 都是 enum Event 的 case (RxSwift/RxSwift/Event.swift)。 入参observer 就是 AnonymousObserver 对象。

如果不知道 observer 怎么来的, 就去 RxSwift/RxSwift/ObservableType+Extensions.swift 路径下看 extension ObservableTypesubscribe 的 56 和 80 行

    override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        observer.on(.next(self._element))
        observer.on(.completed)
        return Disposables.create()
    }
  • observer.on(.next(self._element)) 中 observer 是 AnonymousObserver 对象,但是它并没有 重新 on 方法,所以进入了它的父类 ObserverBase 中,这里我们就看到 on 方法的 入参 event
    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)
            }
        }
    }
  • on 方法调用了 onCore 方法, 因为 AnonymousObserver 实现了这个方法,现在我们要回到 AnonymousObserveronCore 的实现逻辑 。
    override func onCore(_ event: Event<Element>) {
        return self._eventHandler(event)
    }
  • onCore 通过开始初始化保存的闭包 进行回调并赶回了 event 参数(就是在 Just 的 .next(self._element).completed),因为 self._eventHandler(event) 回调 我们又回到了 extension ObservableTypesubscribe(onNext ... 方法的 57 行,进行回调操作,并通过 我们的熟悉 onNext onError onCompleted onDisposed 回调回 最初调用地点。
            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()
                }
            }
  • 至此 小小的 just("1") 就能在闭包中收到 打印 1 了。现在我已经是老泪纵横了(太难了)。

简单的回顾一下我们都去了哪些类和协议:

  • extension ObservableTypestatic func just(_ element: Element) 方法
  • Justinit 方法
  • Producerinit 方法
  • Observableinit 方法
  • extension ObservableTypepublic func subscribe(onNext: ((Element) -> Void)? = nil, onError ... 方法
  • AnonymousObserverinit 方法
  • ObservableasObservable 方法
  • Justsubscribe<Observer: ObserverType>(_ ob 方法
  • ObserverBaseon 方法
  • AnonymousObserveronCore 方法
  • extension ObservableTypesubscribe(onNext 方法的
  • 订阅到信号
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342