RxSwift核心逻辑简介

1,821 阅读7分钟

为什么要使用RxSwift

1、Swift是一种静态语言。静态语言对于数值的传递、响应的回调、通讯等有一定的影响。不像OC有运行时,可以动态的发送消息。所以需要RXSwift来弥补静态语言上的不足。

2、RxSwift的思想是函数响应式编程,很符合Swift函数是一等公民的设计思想,也是以后Swift发展的方向。

3、RxSwift是ReactiveX家族的一员。了解RxSwift后,可以拓展到ReactiveX家族的其他框架。

函数响应式编程

1、函数式

​ 函数来源于数学,用 y = f(x)表示,其中,y是因变量,x是自变量。y会随着x的变化而变化。

​ 在swift中,x相当于一个参数,f是函数,y就是函数的结果—返回值。

​ 在一定情况下,x可以表示为 x = f(x),则,上面的公式可以变形为 y = f(f(x))。即一个函数的参数可以是另一个函数。增加了函数的灵活性。 这就是函数式编程的核心思想。

2、函数响应式

​ 举例说明:

var a: Int = 10        
var b: Int = a + 10 

如果上面的代码中 b 的值需要一直跟随a的值发生变化,我们需要怎么来实现呢?我们需要监听a的值变化,而b响应a的变化而变化。这就是OC中的KVO机制。

但是,很遗憾,Swift中没有KVO键值监听。所以,我们需要RxSwift来实现更高级更方便的函数响应式编程。

体验RxSwift的使用魅力

  • KVO监听person中的name属性
self.person.rx.observeWeakly(String.self, "name")
    .subscribe(onNext:{(value) in
        print(value as Any)
    })
    .disposed(by: disposeBag)
  • 监听按钮的点击事件
self.button.rx.tap
    .subscribe(onNext: {(value) in 
        print("点击了按钮")
    })
    .disposed(by: disposeBag)
  • 监听输入框的输入
self.textFiled.rx.text.orEmpty
    .subscribe(onNext: {(text) in
	print(text)
    })
    .disposed(by: disposeBag)
  • UITextFiled输入绑定UILabel
self.textFiled.rx.text
		.bind(to: self.button.rx.title())
		.disposed(by: disposeBag)
  • 手势监听
let tap = UITapGestureRecognizer()
self.label.addGestureRecognizer(tap)
self.label.isUserInteractionEnable = true
tap.rx.event.subscribe(onNext: {(tap) in
		print(tap.view)
})
.disposed(by: disposeBag)
  • 监听通知
NotificationCenter.default.rx.notifcation(UIResponder.keyboardWillShowNotification)
.subscribe(onNext: {(noti) in
		print(noti)
})
.disposed(by: disposeBag)
  • 定时器
timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)

timer.subscribe(onNext: {(num) in
    print(num)
})
.disposed(by: disposeBag)

RxSwift核心原理分析

RxSwift使用三步曲

第一步:创建序列

let ob = Observable<String>.create { (observer) -> Disposable in
            
    return Disposables.create()
}

第二步:订阅信号

let _ = ob.subscribe(onNext: { (text) in
    print("订阅信息: \(text)")
}, onError: { (error) in
    print("error: \(error)")
}, onCompleted: {
    print("订阅结束")
}) {
    print("已销毁")
}

第三步:发送信号

let ob = Observable<String>.create { (observer) -> Disposable in
            
    // 第三步:发送信号
    observer.onNext("信息1")
            
    return Disposables.create()
}

RxSwift源码分析

  • 首先分析第一步创建序列。使用Observable的create方法创建可观察序列。

查看RxSwift源码

发现好像没有内部实现,只有一个函数声明,那我们去哪里查看实现呢?乔布斯曾经说过,看源码不仅要看代码,还要看文档注释!!!

所以我们往上看注释,会发现有一个「seealso」,翻译过来是「另见」。咦,似乎是需要查看其他文档的意思。并且后面跟了一个链接,那我们是要去看文档吗?

我们先来分析一下这个链接,reactivex.io/documentati…,最后指向了一个create文件的html,那我们猜测是否是源码中有一个Create文件呢,我们现在项目中来搜索一下

搜索后发现确实有一个Create文件,点进去看一下

能找到一个ObservableType的扩展,实现了一个create方法。

其返回值为AnonymousObservable(subscribe)。一个内部匿名可观察序列类。参数subscribe则为第一步创建序列中的闭包。

同时,在这个文件的下方能找到AnonymousObservable匿名内部可观察序列类的实现

实现很简单,init初始化时保存了传入的闭包,至此,第一步创建序列完成。

  • 第二步:订阅信号 使用ObservableType的subscribe订阅信号。

找到源码

分析发现,蓝色框以外的代码作用是回收,真正订阅的关键代码是蓝色方框以内的代码。那我们主要看一下这一部分。
首先创建了一个匿名的观察者AnonymousObserver,其实现和匿名可观察序列类似,都是保存创建时的闭包。函数结束时return一个Disposables对象。

分析到这里大家是不是觉得很奇怪?第一步的可观察序列有了,第二步的观察者也有了,但是他们之间似乎没有联系啊,怎么订阅的?以及第三步的发送信号又是如何执行的呢?

我们找来找去,似乎只可能在

这句代码中,好,我们一起去验证一下我们的猜想。

self.asObservable().subscribe(observer)

我们先看看asObservable(),点击查看一下,咦,点不进去。我们再点查看一下subscribe(observer),咦,好像也找不到实现。好吧,我们再往前看是self,self我们知道是第一步创建的可观察序列

在这个类里面,我们找到了asObservable()subscribe 函数, asObservable()的作用仅仅是返回自身self。

我们再看看subscribe方法。 内部调用了rxAbstractMethod()方法。但是经过查看,这个方法并没有被实现。分析到这里又分析不下去了。我们再回想一下,Observable对象是由create方法创建的。并且其内部是初始化了一个内部匿名可观察序列的实例对象。我们再回到Create文件查看一下源码。发现其也没有subscribe 函数。

但是可以发现,AnonymousObservable类是继承至Producer类,那subscribe函数会不会是其父类Producer的方法呢?

通过查看源码

Producer对象有subscribe函数并且通过断点运行会发现,会走到else中的方法。调用了self.run(observer, cancel: disposer)

在下方找到run函数。发现其内部只有一个rxAbstractMethod()函数调用。真正的run函数并没有实现。其实,这是一种设计模式。有好奇心的宝宝可以自行了解一下。这里就不展开叙述了。这个run函数其实刚才我们已将看到过了,Producer对象的子类AnonymousObservable匿名可观察序列类里

重点来了,敲黑板!!!

在这个方法中,传入了之前创建的匿名观察者AnonymousObserver实例对象。并且创建了一个AnonymousObservableSink实例对象,并调用了它的run()函数。我们看一下这个run()函数的实现。其实是调用了parent._subscribeHandler(AnyObserver(self))parent就是AnonymousObservable的实例。也就是调用了AnonymousObservable._subscribeHandler(AnyObserver(self))

我们在分析第一步创建可观察序列的时候已经知道,这里的_subscribeHandler保存的其实就是第一步创建可观察序列传入的闭包。现在调用_subscribeHandler即是执行了这个闭包。而闭包中的方法就是第三步发送信号

经过上面的源码分析,已经知道了从创建可观察序列-->订阅信号-->发送信号这一系列的数据流转过程。

  • 第三步 发送信号 调用observer.onNext()函数发送信号。

之前已经分析过了,在第二步订阅信号的时候,创建了一个内部匿名观察者observer。这个observer又是如何传递给第一步创建序列的闭包中的呢?下面我们就来分析一下。

我们知道,在第二步订阅信号调用subscribe的return中,调用了Producer对象的subscribe函数,并将observer作为参数传递过去。而在subscribe函数中调用子类AnonymousObservable匿名可观察序列类的run函数时,将observer作为参数传递到了run函数中。

AnonymousObservable.run函数中,初始化AnonymousObservableSink实例时,又将observer传递给了AnonymousObservableSink实例对象。并在调用run函数时,通过AnonymousObservableSink实例对象创建AnyObserver实例,从而传递到了创建序列的闭包中,得到一个观察者observer

通过调用观察者observer对象的onNext()函数,即可调用到第二步订阅信号闭包中的onNext回调。从而发送已经传递订阅信息。

经过上面的分析过程,RxSwift的源码已经分析完毕。RxSwift的核心原理也了解得比较清晰。但是,RxSwift中所用到的设计模式已经编程思想却是需要我们在以后的使用中不断学习已经掌握的。

最后,附上RxSwift的一个源码分析思维导图,希望对大家有所帮助。