RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)

RXSwift GitHub地址
RXSwift中文文档
RX家族

絮叨:
这篇之所以讲核心逻辑时很仔细(啰嗦),是因为其重要性,必须要给弄懂了!。

简介

全称ReactiveX for Swift,是一个简化异步编程的框架,实现了函数响应式编程,事件与对象紧密联系,业务流清晰,便于管理。在RxSwift中,所有异步操作(事件)和数据流均被抽象为可观察序列的概念。
流程为:
创建序列 -> 订阅序列 -> 发送信号 -> 信号接收

简单使用:

  • 框架导入: CocoaPods
pod 'RxSwift'
pod 'RxCocoa'
//友情提示 当使用  Moya-ObjectMapper 时,由于此库引用了RxSwift,所以如果有pod 'Moya-ObjectMapper/RxSwift'时,无需再pod 'RxSwift'
写为:
#pod 'RxSwift'
pod 'RxCocoa'
pod 'Moya-ObjectMapper/RxSwift'

在需要使用的类中添加依赖:

import RxCocoa
import RxSwift
  • 简单用法:
    1 : KVO
class LBPerson:NSObject{
    @objc dynamic var name : String = "default"
}

extension LBRegisterViewController{
    fileprivate func kvoTest(){
        let person = LBPerson.init()
        person.rx.observeWeakly(String.self, "name")
            .subscribe(onNext: { (value) in
            print(value as Any)
        })
        .disposed(by: disposeBag)
        
        person.name = "lb"
    }
}

输出结果:

Optional("lb")

2 : UIButton 事件响应

fileprivate func btnTest(){
    let btn = UIButton()
    btn.rx.tap.subscribe(onNext: { (_) in
        print("事件")
    })
}

/*注:tap默认为TouchUpInside. 点进去看源码*/
extension Reactive where Base : UIButton {

    /// Reactive wrapper for `TouchUpInside` control event.
    public var tap: RxCocoa.ControlEvent { get }
}

//那么其他类型Event呢: 你看-->
btn.rx.controlEvent(.touchUpOutside).subscribe(onNext: { (_) in
    print("事件")
})

输出:

"事件"

3: UITextFiled 键盘内容监听

fileprivate func TFTest(){
    let tf = UITextFiled()
    let textFieldInputSequence = tf.rx.text.orEmpty.asDriver().throttle(0.4)

    textFieldInputSequence.drive(onNext: { (str) in
            print("tf值改变-->\(str)")
    }).disposed(by: disposeBag)
}

// orEmpty,防空处理.
// throttle节气阀,防暴力触发,参数为时间间隔.

4: UIScrollView ContentOffser监听

let scrollView = UIScrollView()
scrollView.rx.contentOffset
   .subscribe(onNext: { [weak self](content) in
       print(scrollView.contentOffset.y)
   })
.disposed(by: disposeBag)

5: 手势监听

let tap = UITapGestureRecognizer()
let label = UILabel()
label.addGestureRecognizer(tap)
label.isUserInteractionEnabled = true
tap.rx.event.subscribe(onNext: { (tap) in
    print(tap.view)
})
.disposed(by: disposeBag)

6: 通知

NotificationCenter.default.rx.notification(UIResponder.keyboardWillShowNotification)
    .subscribe(onNext: { (noti) in
        print(noti)
    })
.disposed(by: disposeBag)

7: 定时器

let timer = Timer.init()
timer = Observable.interval(1, scheduler: MainScheduler.instance)
timer.subscribe(onNext: { (num) in
    print(num)
}).disposed(by: disposeBag)

8: 网络(URLSession)

let url = URL(string: "https://www.baidu.com")
//        原本写法
//        URLSession.shared.dataTask(with: url!) { (data, response, error) in
//            print(String.init(data:data!,encoding: .utf8))
//        }.resume()
        
URLSession.shared.rx.response(request: URLRequest(url: url!))
   .subscribe(onNext: { (response,data) in
       print(response)
   }).disposed(by: disposeBag)

这个看起来有点鸡肋,后续文章中会给大家介绍RXSwift结合MOYA使用,从而更优雅的调用网络。先看个效果:

let provider = MoyaProvider();

provider.request(.login(username: "haha", password: "123456", token: "***")) { (result) in
     if result.error == nil{
          LBLog(result.value);
     }
}

核心逻辑:

重点:重头戏它又来了.

先来个最简单的响应流程:

fileprivate func exploringTest(){
   let ob = Observable.create { (observer) -> Disposable in
       observer.onNext("测试")
       observer.onCompleted()
       return Disposables.create()
   }
        
   _ = ob.subscribe(onNext: { (text) in
       print("订阅到:\(text)")
   }, onError: { (error) in
       print("error:\(error)")
   }, onCompleted: {
       print("完成")
   }, onDisposed: {
       print("销毁")
   })
}

打印结果:

订阅到:测试
完成
销毁

以上便是一个序列,从创建,到订阅,发送,接收,销毁的全过程。
那么接下来我们来撩开它滴裙子

一步一步来,

  • 先来看Observable.create
    首先Cmd+点击Observable,进来了,找了一堆没找着.create,不急,看图
    RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第1张图片
    Observable.create

    选择Create.Swift, 看到了啥,第一个就是ObservableType的create方法
RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第2张图片
Observable.create方法实现

小注: 有滴同学说我找的是Observablecreate方法,你找的这个不是ObservableType吗。
答: 方法查找流程。那么Observable点进去你看

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第3张图片
ObservableType与Observable关系

好滴,找到了create实现。

总结:我们看到我们所写的Observable.create其实就是return了一个AnonymousObservable对象的构造方法,也就是返回了一个AnonymousObservable对象。这个对象中储存了我们发送的事件,需要回调的处理。

继续,本文件搜索AnonymousObservable,找到这个类

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第4张图片
找到AnonymousObservable

找到构造方法具体实现了
我们看到它啥也没干,只是把传给自己的匿名函数用成员变量保存了下来。OK, Observable.create干了啥我们知道了。继续-->

  • ob.subscribe
    第二句代码ob.subscribe
    老规矩 先点进去再说,CMD+点subscribe
    RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第5张图片
    ObservableType.subscribe

    我再点:额。方法实现不给看了。 无妨,既然你都告诉我了是ObservableTypesubscribe(onNext:balabala方法,那我自己找。还是看图:
    RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第6张图片
    图666: ObservableType的subscribe(onNext:...方法实现

好我们来到了重点了:
首先Disposable放过不管
图中第一个绿框,创建了一个AnonymousObserver订阅者对象。又是构造方法,又不给点进去?,没关系,我们自己查:

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第7张图片
AnonymousObserver构造方法

绿框框里看到啥,AnonymousObserver 的初始化构造方法时init(_ eventHandler: @escaping EventHandler),利用逃逸闭包写法,当逃逸闭包被当作函数参数初始化时,可以把闭包写开,这个gay位同学应该问题不大。

总结:
第一个绿框中干了啥?
一句话:创建了一个AnonymousObserver对象,并且在创建时就保存了传进来的eventHandler的Block到自己的成员变量中。

ok,继续看图666中,AnonymousObserver创建后,第二个绿框,return的时候调用了self.asObservable().subscribe(observer)方法 (Disposables不用管,后续我会专门写一篇文章来介绍垃圾袋机制).

注意:注意:坑来了啊,self.asObservable().subscribe(observer),提问:想看subscribe的实现,那我们改找哪个类。
Observable? 错啦。仔细回忆下第一句代码,Observable.create时做了什么,上面第一句代码总价加粗的字体:

因为第一句代码返回了一个AnonymousObservable对象。所以此时self指的是AnonymousObservable对象,而asObservable()则是return了一个self,啥也没干,因此我们需要去找AnonymousObservable的subscribe()方法

不信?看图,


RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第8张图片
self.asObservable().subscribe(observer)中,self指的是谁

走到这 ,恭喜,裙底的风光快显露了。
继续,找AnonymousObservable的subscribe()方法,同样在Create.swift文件中.

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第9张图片
AnonymousObservable对象

what the hell?为什么对象里没得subscribe()方法。 别急,子类找不着找谁?找爸爸。CMD+点Producer

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第10张图片
Producer调用subscribe()方法

图上看到,不管 if / else 都会创建SinkDisposer类, 然后调用self.run方法.
注意: 别忘了,儿子 AnonymousObservable重写了run方法,儿子没得方法才找到的爸爸 Producer
因此回到 AnonymousObservable中,

终于被我看见裙底了。


RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第11张图片
AnonymousObservable对象,run方法

创建了AnonymousObservableSink对象,调用其run方法,

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第12张图片
run

run干了啥?调用传参中parent的Block,传进来的parent是谁?

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第13张图片
执行谁的_subscribeHandler

传进来是self,那self的 _subscribeHandler是谁?
ok 第一句代码create时我们保存的,也就是说,

总结:图666中第二个绿框(也就是self.asObservable().subscribe(observer))干了啥.
一: 保存了接收到事件时的回调.
二: 执行我们创建序列时的回调.

换句话说,此时接下来就走到了序列创建回调中。


RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第14张图片
序列创建回调
  • 执行observer.onNext("测试")
    observer是谁呢,此处比较饶人,我补充了一片文章专门讲解,贴上链接RXSwift响应核心底层逻辑原理补充

那么接下来我们查找 AnonymousObserveron() 方法

RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第15张图片
AnonymousObserver类

没找着on(Next)方法?找父类 ObserverBase
RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第16张图片
ObserverBase类以及on(_ event: Event)方法

方法里使用了个 switch,最后都调用了 self.onCore(event)方法,由于子类 AnonymousObserver重写了onCore方法所以回到子类调用(不信你看 大大的override写着),最终找到执行保存的 _eventHandler,参数为调用onNext时传递的参数,也就是我们写的字符串"测试",也就是我们创建订阅者时传进来的收到订阅回调。
RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第17张图片
以及onCore方法

至此:从创建序列 -> 订阅序列 -> 发送信号 -> 信号接收整个流程我们已经分析完毕。(我都觉得自己啰嗦的不行,但是没办法,谁让是重点,老老实实吃透吧)。

最后流程总结:画图(改图为引用自Cooci老师)


RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇)_第18张图片
响应流程核心原理完整流程

写这篇博客花了3个多小时,学习是枯燥的过程,但是坚持下来的时候是最爽的。

你可能感兴趣的:(RXSwift基础用法及响应核心底层逻辑原理(超详细吐血篇))