美文网首页
RxSwift核心逻辑底层剖析(一)

RxSwift核心逻辑底层剖析(一)

作者: 越来越胖了 | 来源:发表于2019-07-21 21:55 被阅读0次
    RXSwift.jpg

    要对RX的核心逻辑有所了解,首先应该对Swift的闭包能够很好的理解。
    在Swift的AIP中有如下的一个描述:
    闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的匿名函数(Lambdas)比较相似。

    闭包可以捕获和存储其所在上下文中任意常量和变量的引用。被称为包裹常量和变量。 Swift 会为你管理在捕获过程中涉及到的所有内存操作。
    Swift的AIP的在线查看地址:https://www.runoob.com/manual/gitbook/swift5/source/_book/chapter2/07_Closures.html

    本文首先是以block的方式去理解RX的逻辑的实现的。
    RXSwift的核心逻辑分为三步:

    1. 创建可观察序列
     let observa = Observable<Any>.create { (obserber) -> Disposable in
                
                print("create的内部打印--1")
                //obserber.onNext("onNext--1")
                //obserber.onNext("onNext--2")
                //obserber.onCompleted()
                print("create的内部打印--2")
                return Disposables.create()
            }
    

    这里附上RX家族对create函数的解释:
    http://reactivex.io/documentation/operators/create.html
    大概意思就是(百度翻译的0.0):
    您可以使用Create 运算符从头开始创建Observable 。您将此运算符传递给接受观察者作为其参数的函数。通过调用观察者的-因此,它表现为一个可观察写这个功能onNext, onError和onCompleted适当的方法。

    格式良好的有限Observable必须尝试将观察者的onCompleted 方法恰好调用一次或者只调用其onError方法一次,并且此后不得尝试调用任何观察者的其他方法。
    我的理解就是:
    create后面其实是一个闭包,接收一个(obserber) 后返回Disposable,
    其实也就是一个block(可以这样去理解),如果我们就这样直接运行代码,是不会得到任何打印的,因为没有一个self.block(obserber)的调用。所以就涉及到RX的第二步:
    2.订阅

    let _ = observa.subscribe(onNext: { (text) in
                print("订阅到:\(text)")
            }, onError: { (error) in
                print("error: \(error)")
            }, onCompleted: {
                print("完成")
            }) {
                print("销毁")
            }
    

    通过observa.subscribe(....),会让程序去执行create后面的闭包,所以我们会第一时间得到一个 "create的内部打印"
    而在observa.subscribe内部,onNext,onError,onCompleted,分别都是对应了一个闭包(一个block的实现),而这个block代码块的调用是在
    { (obserber) -> Disposable in
    //在这里去对observa.subscribe里面的block实现进行了一个调用
    }

    所以RX的核心步骤第三步是在:

     let observa = Observable<Any>.create { (obserber) -> Disposable in
                
                print("create的内部打印")
                // 第三步:发送信号
                obserber.onNext("onNext--1")
                obserber.onNext("onNext--2")
                obserber.onCompleted()
                print("create的内部打印--2")
                return Disposables.create()
            }
    

    以上代码运行会打印如下:


    屏幕快照 2019-07-21 17.02.09.png

    如果用在一个rx的实际例子中:比如btn的点击
    swift的写法是:

    self.button.addTarget(self, action: #selector(self.buttonClick(btnclick:)), for: .touchUpInside)
    

    RXSwift就是在这个addTarget方法基础上添加了一个 RX内部类: self.button.addTarget(RX内部类),
    然后通过 RX内部类 去实现了 #selector( ...... ) , 而selector里面实现是通过 selector( obserber.onNext() ) ,obserber.onNext() 调用的就是一个btn 的 selector事件具体实现的代码块。

    WechatIMG2.jpeg

    以下我们通过对源码的查看验证步骤是否正确:
    1.查看create方法


    屏幕快照 2019-07-21 17.38.43.png

    发现方法返回了一个 内部类(AnonymousObservable)的初始化AnonymousObservable(subscribe),
    2.查看这个内部类


    1.jpeg

    可以看到内部类(AnonymousObservable)调用了init方法初始化保存了subscribe,也就是create方法后面的闭包。

    3.查看observa.subscribe


    2.jpeg

    let observer 这个常量指向了一个 AnonymousObserver<E>类,后面还一个尾随闭包,通过AnonymousObserver的实现可以看到
    对 subscribe创建的 onNext,onError,onCompleted,onDisposed 四个闭包进行了保存。


    111563704558_.pic.jpg 其中实现图片 (名称 WechatIMG2)中2-->3步骤的是如下方法 WechatIMG18.jpeg
    WechatIMG18.jpeg

    通过 Disposables.create 方法去调用了self.asObservable().subscribe(observer),其中对onNext,onError,onCompleted,onDisposed的判断则在subscribe(observer)方法中。

    最后,这里在做一点补充,点击observa.subscribe去查看内部实现时,我打了两个断点,如图:

    11.png
    我在56行,和79行下了断点,运行代码,就会发现,首先是56号断点执行,然后程序并不是直接到79号断点,而是会多出进入
    public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
            -> Disposable {
    

    一直到我们创建的observa.subscribe执行完毕,才会走79号断点return。

    原因是:这个地方断的是 return的函数,这个return的函数是会先执行 参数(self.asObservable().subscribe(observer),disposable) 然后给我们的参数回调值
    .也就是说,我们的函数内的参数,如果是一个函数,那么会先执行参数函数

    相关文章

      网友评论

          本文标题:RxSwift核心逻辑底层剖析(一)

          本文链接:https://www.haomeiwen.com/subject/hhqvlctx.html