一、RxSwift核心
1、observable订阅流程
RxObservable继承链:
Producer:Observable > subscribe > currentThreadScheduler > self.run() > setSinkAndSubscription()
subscribe:AnonymousObserver(内部观察者)<eventHandler> > [ObserverBase](on onCore dispose) > [ObserverType](on)
public class Observable<Element> : ObservableType {
init() {
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
}
public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
rxAbstractMethod()
}
public func asObservable() -> Observable<Element> { self }
deinit {
#if TRACE_RESOURCES
_ = Resources.decrementTotal()
#endif
}
}
-
Observable实现了一个协议ObservableType,而且ObservableType协议继承自ObservableConvertibleType协议,所以在Observable中实现了两个协议方法:subscribe和asObservable。 -
subscribe方法没有具体实现的逻辑,需要子类去实现。 -
asObservable方法返回的是self,看似用处不大,其实不是这样的。asObservable是非常有用的,如果一类是Observable的子类,我们可以直接返回self,如果不是Observable的子类,我们可以通过重写这个协议方法来返回一个Observable对象,这样保证了协议的一致性。在使用的时候我们可以直接写类似self.asObservable().subscribe(observer)这样的代码,有利于保持代码的简洁性,是良好的封装性的体现。 -
_ = Resources.incrementTotal()和_ = Resources.decrementTotal()这两行代码其实是RxSwift内部实现的一个引用计数。这部分内容我会在后面的文章中再详解。
AnonymousObservableSink 的作用
final private class AnonymousObservableSink<Observer: ObserverType>: Sink<Observer>, ObserverType {
typealias Element = Observer.Element
typealias Parent = AnonymousObservable<Element>
// state
private let isStopped = AtomicInt(0)
#if DEBUG
private let synchronizationTracker = SynchronizationTracker()
#endif
override init(observer: Observer, cancel: Cancelable) {
super.init(observer: observer, cancel: cancel)
}
func on(_ event: Event<Element>) {
#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()
}
}
}
func run(_ parent: Parent) -> Disposable {
parent.subscribeHandler(AnyObserver(self))
}
}
-
AnonymousObservableSink是Sink的子类,AnonymousObservableSink本身遵守ObseverType协议,与此同时实现了run方法,虽然没有实现subscribe方法,但是已经足够了,这样AnonymousObservableSink从某种程度来说也是Observable。 -
AnonymousObservableSink是Observer和Observable的衔接的桥梁,也可以理解成管道。它存储了_observer和销毁者_cancel。通过sink就可以完成从Observable到Obsever的转变。 -
在
run方法中的这行代码parent._subscribeHandler(AnyObserver(self)),其中parent是一个AnonymousObservable对象。_subscribeHandler这个block调用,代码会执行到创建序列时的block。然后会调用发送信号的代码obserber.onNext("发送信号"),然后代码会经过几个中间步骤会来到AnonymousObservableSink类的on方法。 -
其中
AnyObserver(self)中的 self 就是observer是一个函数(function)on 。
完善核心流程图:
2、timer内部分析
我们常用的定时器:
NSTimerGCDCADiplayLink
直接上代码分析:
//创建定时器
timer = Timer.init(timeInterval: 1, target: self, selector: #selector(timerFire), userInfo: nil, repeats: true)
timer.fire()
RunLoop.current.add(timer, forMode: .common)//加入runloop
//函数式写法
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { timer in
print(timer)
})
//GCD写法
gcdTimer = DispatchSource.makeTimerSource()
gcdTimer?.schedule(deadline: .now(), repeating: .seconds(1))
gcdTimer?.setEventHandler(handler: {
print("hello GCD")
})
gcdTimer?.resume()
gcdTimer?.suspend()
gcdTimer?.cancel()
gcdTimer = nil
//CADisplayLink写法
cadTimer = CADisplayLink写法(target: self, selector: #selector(timerFire))
cadTimer?.preferredFramesPerSecond = 1
cadTimer?.add(to: .current, forMode: .common)
那如果使用RxSwift要如何实现呢?如何保证定时器的精确性呢?
Observable<Int>.timer(.seconds(1), period: .seconds(1), scheduler: MainScheduler.instance)
.subscribe { result in
print(result)
}
.disposed(by: disposeBag)
RxSwift的timer底层实现是GCD,我们看下源码:
Timer 序列分为两种类型.
一次性执行: 创建一个 Observable 在一段延时后,产生唯一的一个信号.一般用于某些只需要执行一次的延迟操作.如超时判断.重复多次执行: 创建一个 Observable 在一段延时后,每隔一段时间产生一个信号.
跟踪点开timer:
public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval? = nil, scheduler: SchedulerType)
-> Observable<Element> {
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler
)
}
发现Timer 继承着Producer(生产者),在RxSwift 中,序列大部分都是继承者Producer的.我们在设计一些代码时,通过会让功能相似的类继承着同一基类BaseClass,这里可以理解为Producer就是这些序列的基类,在基类中实现了序列的一些基本操作.例如订阅功能Subscribe().
运行代码调试:
发现self.period有值执行如上代码,创建执行
TimerSink > sink.run() 然后继续进入代码(run() -> Disposable):
func run() -> Disposable {
return self.parent.scheduler.schedulePeriodic(0 as Observer.Element, startAfter: self.parent.dueTime, period: self.parent.period!) { state in
self.lock.performLocked { // 使用递归锁,防止互斥 RecursiveLock
self.forwardOn(.next(state)) //发送消息 - 执行回调
return state &+ 1 //state 加1
}
}
}
继续跟踪断点:
判断如果disposed值发送改变,大概意思就是如果开始执行回收了,则直接返回,不执行 on发送消息了。
归纳百川汇de->on函数
self.observer.on(event)这段代码就是执行(->onCore),回调闭包代码,就是我们上面分析的核心流程,作者的思想确实厉害,归纳百川回流大海=on
初步了解sink思想:(AnonymousObserver水管(管理者或者生产者) -> (不同的管道)sink -><实现ObserverType>)on 函数在根据不同的 Element 类型进行分发执行回调函数(.next .error .completed)。
补充:Observable的各种创建方式
// 首先来一个空的序列 - 本来序列事件是Int类型的,这里调用emty函数 没有序列,只能complete
print("******** empty ********")
let emtyOb = Observable<Int>.empty()
_ = emtyOb.subscribe(onNext: { number in
print("订阅:", number)
}, onError: { error in
print("error:", error)
}, onCompleted: {
print("完成回调")
}) {
print("释放回调")
}
// 单个信号序列创建
let array = ["NY_EDU", "YYDS"]
Observable<[String]>.just(array)
.subscribe { event in
print(event)
}.disposed(by: disposeBag)
_ = Observable<[String]>.just(array)
.subscribe(onNext: { number in
print("订阅:", number)
}, onError: { error in
print("error:", error)
}, onCompleted: {
print("完成回调")
}) {
print("释放回调")
}
// 多个元素 - 针对序列处理
Observable<String>.of("NY_EDU", "YYDS")
.subscribe { event in
print(event)
}.disposed(by: disposeBag)
// 字典
Observable<[String: Any]>.of(["name":"LG_EDU", "age":18])
.subscribe { event in
print(event)
}.disposed(by: disposeBag)
// 数组
Observable<[String]>.of(["NY_EDU", "YYDS"])
.subscribe { event in
print(event)
}.disposed(by: disposeBag)
// 从集合中获取序列:数组,集合,set 获取序列 - 有可选项处理 - 更安全
Observable<[String]>.from(optional: ["NY_EDU", "YYDS"])
.subscribe { event in
print(event)
}.disposed(by: disposeBag)
总结
RXSwift核心原理
三部曲:创建序列(observable) ,订阅序列,发送信号(消息)核心中的订阅流程:订阅subscribe->(创建AnonymousObserver点阅者,保存event闭包,创建AnonymousObservableSink 管道生产者) -AnonymousObservableSink:这个家伙干了很多事,我们称它大号下水管道,根据不同的需求分流到不同的(sink)管道。on函数:AnyObserver.on('我胡汉三又回来了')遵循了ObservableType协议分发(发送响应):回调到具体的函数(.next .error .completed)代码块
然后我们用RxSwift.timer 定时器来分析了(内部实现原理):
Timer序列:分两种,一次性执行,重复多次执行。Timer是GCD:DispatchSourceTimer实现的定时器。forwardOn:最终回到AnyObserver.on 回调函数。