响应式编程是RxSwift的核心思想,统一思想快速开发。同样在ReactiveX系列中其他语言也都使用了这一思想,当我们掌握了RxSwift
运用,那么RxJava
,RxPHP
,RxJs
等等都能够快速上手。那么RxSwift
是如何响应的呢?下面就来看一下源码都做了哪些事情。
RxSwift核心流程
1、创建序列
2、订阅序列
3、发送信号
先看一下是如何使用的,代码如下:
//1、创建序列
let obs = Observable.create { (observer) -> Disposable in
//3、发送信号
observer.onNext("我是一条消息")
return Disposables.create()
}
//2、订阅序列
obs.subscribe(onNext: { (val) in
//4、序列监听
print("onNext:\(val)")
}).disposed(by: disposeBag)//5、打包待销毁
- 通过
Observable
的create
创建序列,在create
闭包内调用onNext
方法实现信号发送 - 调用
subscribe
方法订阅序列,并实现subscribe
的参数闭包onNext
,在闭包内监听信号 - 最后通过
disposed
对序列打包等待销毁
看到代码可能会疑惑,消息是如何发给订阅者的。按正常逻辑,订阅后才能收到信息,那么可以猜测,在成为订阅者并布置好监听后,订阅者向序列发送了一条消息,通知可观察序列可以发信号了。大致可整理为如下流程:
以上只是猜测,下面来看具体的代码实现。在RxSwift
中同名的方法有很多,很难做到直接定位代码位置,我们可以通过command+点击
配合断点一步步找到对应方法的底层实现。
1、创建序列
public static func create(_ subscribe: @escaping (AnyObserver) -> Disposable) -> Observable {
return AnonymousObservable(subscribe)
}
该方法是对ObservableType
协议的扩展,最外层实现的闭包subscribe
则作为参数传入AnonymousObservable
,并返回AnonymousObservable
对象,继续执行追踪到AnonymousObservable
类,如下:
final private class AnonymousObservable: Producer {
typealias SubscribeHandler = (AnyObserver) -> Disposable
let _subscribeHandler: SubscribeHandler
//初始化时保存闭包
init(_ subscribeHandler: @escaping SubscribeHandler) {
self._subscribeHandler = subscribeHandler
}
override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}
首先看一下AnonymousObservable
的继承链如下:
- AnonymousObservable -> Product -> ObservableType -> ObservableConvertible
在父类Product
中好像有我没需要的方法:
override func subscribe(_ observer: O) -> Disposable where O.E == Element {
}
像是订阅方法,但不是,但也有着千丝万缕的联系。到此为止,序列创建部分已完成,可总结如下:
-
create
方法实现参数闭包,内部创建AnonymousObservable
对象 -
AnonymousObservable
对象保存了外界实现的闭包 -
Producer
中的subscribe
方法,应该是订阅后将要调用的方法
记住以上三点,后序逐一对比。
2、订阅序列
根据方法名找到subscribe
的实现,command+点击
直接进入实现,源码如下(取部分源码):
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
//此处省略若干行代码
let observer = AnonymousObserver { 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
)
}
该方法是对ObservableType
的拓展。在方法内部已经出现对观察者的定义,AnonymousObserver
类型的闭包observer
。
源码分析:
2.1、observer
内部调用的外部(应用层)实现的闭包,由此看出所有信号是由此发出,event
是observer
的参数,不难看出,observer
闭包也是在其他地方调用,传入带有信号值的event
参数
2.2、observer
被当做参数传入到subscribe
中,而observer
的调用必然是在subscribe
中实现的
self.asObservable().subscribe(observer)
2.3、self.asObservable()
该方法返回本身,保证协议的一致性,方法如下:
public class Observable : ObservableType {
// 省去代码若干
public func asObservable() -> Observable {
return self
}
}
2.4、继续断点执行找到subscribe
方法,正是上面所提到的Producer
中的方法,方法如下:
override func subscribe(_ observer: O) -> Disposable where O.E == Element {
// 省去代码若干
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
2.5、紧接着我的observer
观察者被传入到run
中,上面说到该观察者一定会被调用,继续深入
let sinkAndSubscription = self.run(observer, cancel: disposer)
2.6、继续断点执行,发现self.run
的调用,调用的是AnonymousObservable
中的run
方法,代码如下:
final private class AnonymousObservable: Producer {
typealias SubscribeHandler = (AnyObserver) -> Disposable
let _subscribeHandler: SubscribeHandler
init(_ subscribeHandler: @escaping SubscribeHandler) {
self._subscribeHandler = subscribeHandler
}
override func run(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}
2.7、此处就是创建序列时的AnonymousObservable
类。在run
方法类创建了sink
对象,在初始化时传入了我们上面所说的观察者,记住sink
保存了观察者observer
闭包,并且调用了sink.run(self)
方法,传入的是创建时产生的可观察序列observable
闭包对象,深入run
:
final private class AnonymousObservableSink: Sink, ObserverType {
typealias E = O.E
typealias Parent = AnonymousObservable
// 省去代码若干
// 此处向父类Sink初始化了observer对象
override init(observer: O, cancel: Cancelable) {
super.init(observer: observer, cancel: cancel)
}
func run(_ parent: Parent) -> Disposable {
return parent._subscribeHandler(AnyObserver(self))
}
}
2.8、拨开云雾见天日,此处parent
由let subscription = sink.run(self)
传入,self
即为创建序列create
方法返回的observable
对象,而_subscribeHandler
是创建序列所保存的闭包,此时我们的闭包就被调用了,被调用闭包如下:
let obs = Observable.create { (observer) -> Disposable in
//3、发送消息
observer.onNext("我是一条消息")
return Disposables.create()
}
发送信号的闭包被调用,接下来就是信号发送了。
3、发送信号
根据上面步骤继续探索,代码已经执行到我们的业务层。
在信号发送闭包中通常调用一下三种方法,用来发送信号。如下:
-
observer.onNext("我是一条消息")
信号发送 -
observer.onCompleted()
序列完成,完成后序列将被释放 -
observer.onError(error)
序列出错中断,序列不可继续使用,被释放
以上三个方法为ObserverType
的拓展方法
extension ObserverType {
/// Convenience method equivalent to `on(.next(element: E))`
///
/// - parameter element: Next element to send to observer(s)
public func onNext(_ element: E) {
self.on(.next(element))
}
/// Convenience method equivalent to `on(.completed)`
public func onCompleted() {
self.on(.completed)
}
/// Convenience method equivalent to `on(.error(Swift.Error))`
/// - parameter error: Swift.Error to send to observer(s)
public func onError(_ error: Swift.Error) {
self.on(.error(error))
}
}
-
E
表示了一个泛型信号量,可表示任意类型的信号 -
.next(element)
是一个带泛型参数的枚举,管理了三种类型事件的消息传递。如下:
public enum Event {
/// Next element is produced.
case next(Element)
/// Sequence terminated with an error.
case error(Swift.Error)
/// Sequence completed successfully.
case completed
}
on
这是AnonymousObservableSink
中的方法,代码如下:
final private class AnonymousObservableSink: Sink, ObserverType {
typealias E = O.E
typealias Parent = AnonymousObservable
// 代码省略若干行
func on(_ event: Event) {
#if DEBUG
self._synchronizationTracker.register(synchronizationErrorMessage: .default)
defer { self._synchronizationTracker.unregister() }
#endif
switch event {
case .next:
if load(&self._isStopped) == 1 {
return
}
self.forwardOn(event)
case .error, .completed:
if fetchOr(&self._isStopped, 1) == 0 {
self.forwardOn(event)
self.dispose()
}
}
}
}
内部根据Event
枚举不同成员变量做不同的信号发送,信号发送调用了forwardOn
方法。方法实现如下:
class Sink : Disposable {
init(observer: O, cancel: Cancelable) {
self._observer = observer
self._cancel = cancel
}
final func forwardOn(_ event: Event) {
if isFlagSet(&self._disposed, 1) {
return
}
self._observer.on(event)
}
}
代码有些长只保留了核心部分,Sink
即AnonymousObservableSink
的父类,见上文2.7处描述
,_observer
即是订阅中在内部产生的AnonymousObserver
对象,而该对象调用了on
方法并传递了信号。on
方法所在位置如下:
- AnonymousObserver -> ObserverBase -> on()
class ObserverBase : Disposable, ObserverType {
typealias E = ElementType
func on(_ event: Event) {
switch event {
case .next:
if load(&self._isStopped) == 0 {
self.onCore(event)
}
case .error, .completed:
if fetchOr(&self._isStopped, 1) == 0 {
self.onCore(event)
}
}
}
}
在方法内部又掉用了self.onCore(event)
,此时该方法在AnonymousObserver
中实现,代码如下:
final class AnonymousObserver : ObserverBase {
typealias Element = ElementType
typealias EventHandler = (Event) -> Void
private let _eventHandler : EventHandler
init(_ eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
override func onCore(_ event: Event) {
return self._eventHandler(event)
}
}
源码分析
- 此处通过
_eventHandler
来发送信号,_eventHandler
是从哪来的呢?逆推onCore
调用者是observer
,而observer
是订阅时在内部创建的,被一层层传入到此 - 而在
observer
初始化时即被保存为
_eventHandler
,_eventHandler
调用即调用了订阅时创建的observer
闭包,进而信号又通过闭包内的闭包传出到业务层
//2、订阅序列
obs.subscribe(onNext: { (val) in
print("onNext:\(val)")
}).disposed(by: disposeBag)
天呢!容我喘口气~~
至此我们响应式编程的创建、订阅、发送、接收等流程就已完成。整个流程会觉得很复杂,但它统一了所有事件的创建与监听,统一思想快速开发,今后的开发流程就是:
- 创建序列 -> 订阅序列 -> 发送序列 -> 响应序列
sink在Rx中充当管理者,管理序列,观察者和销毁者,将序列发送至观察者,并管理销毁者适时消耗序列,回收资源。
最后附上两张总结图: