RxSwift 内部是如何运行的,Observable 与 Observer 之间存在什么关系,Operator 又是如何实现的,如果想彻底弄清楚 RxSwift,我们可以自己写一个简单的 RxSwift,帮助自己真正理解其实现原理,从而更好地使用 RxSwift 进行开发。
基本原理
RxSwift 是观察者模式的拓展版,但归根结底还是观察者模式。用户输入、点击事件、定时器、网络请求等都可以当成 Observable(被观察者),Observer(观察者)总会在 Observable 处注册一个订阅,当事件发生时,Observable 找到所有的订阅并通知观察者。
观察者模式
简单介绍下观察者模式,已经熟悉的可以跳过这一段。
当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并做出反应。比如在 MVC 中,Model 就是观察者模式中的被观察者(Subject),View 是观察者模式中的观察者(Observer),当 model 发生改变里,触发通知监听它的 view 进行更新。
我们用 Swift 写一个简单的观察者:
//Observer pattern
protocol Observer {
func update(message: String)
}
class Subject {
var observers: Array<Observer> = []
func register(observer:Observer) {
self.observers.append(observer)
}
func notify(message: String) {
for observer in observers {
observer.update(message: message)
}
}
}
class Observer1: Observer {
func update(message: String) {
print("Observer1: " + message)
}
}
class Observer2: Observer {
func update(message: String) {
print("Observer2: " + message)
}
}
被观察者 Subject 类内部存储了订阅它的对象,当 Subject 有更新时,就会通知这些订阅的 Observer。
let subject = Subject()
let observer1 = Observer1()
let observer2 = Observer2()
subject.register(observer: observer1)
subject.register(observer: observer2)
subject.notify(message: "zcj")
Observable
Observable 本质上是一个函数,接受一个订阅函数,当有事件发生时,触发这个订阅函数进行更新。
//simple 1: Observable
typealias EventHandler = (String) -> Void
func myObservable(eventHandler: EventHandler) {
eventHandler("zcj")
eventHandler("hello")
eventHandler("world")
}
let eventHandler : EventHandler = {(value) -> Void in
print(value)
}
myObservable(eventHandler: eventHandler)
上面定义了一个闭包 EventHandler,传入一个 String 参数,无返回值。实例化一个闭包对象 eventHandler,只是简单地打印传入的内容。
函数 myObservable,接收一个闭包,并根据需要调用这个闭包。
Observer
我们把 Observable 封装成一个类,这样可以很方便地把 Observer 当做匿名对象传进去,以一种简单的方式来使用,先看最终的使用方式
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
observable.subscribe(eventHandler: closure)
为了实现这个效果,首先把订阅函数封装进 Observer 类,增加一个 next 函数,next 函数被调用时,执行 Observer 所持有的订阅函数。
//simple 2:Observer
class Observer {
typealias EventHandler = (String) -> Void
private let _eventHandler : EventHandler
init(eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
func next(value: String) {
self._eventHandler(value)
}
}
func myObservable(handle: @escaping (String) -> Void) {
let observer = Observer(eventHandler: handle)
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
myObservable(handle: closure)
Observable 也包装成类,通过 subscribeHandler 把 Observer 以内在的形式创建
//simple 3
typealias EventHandler = (String) -> Void
typealias SubscribeHandler = (Observer) -> Void
class Observer {
private let _eventHandler : EventHandler
init(eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
func next(value: String) {
self._eventHandler(value)
}
}
class Observable {
private let subscribeHandler: SubscribeHandler
public init(_ subscribeHandler: @escaping SubscribeHandler) {
self.subscribeHandler = subscribeHandler
}
public func subscribe(eventHandler: @escaping EventHandler) {
let observer = Observer(eventHandler: eventHandler)
self.subscribeHandler(observer)
}
}
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
observable.subscribe(eventHandler: closure)
Operator
RxSwift 中的操作符其实是一个接收源 Observable,然后加工处理后返回一个新的 Observable,我们实现一个简单的 map 操作符,代码如下:
//simple 4
typealias EventHandler = (String) -> Void
typealias SubscribeHandler = (Observer) -> Void
class Observer {
private let _eventHandler : EventHandler
init(eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
func next(value: String) {
self._eventHandler(value)
}
}
class Observable {
private let subscribeHandler: SubscribeHandler
public init(_ subscribeHandler: @escaping SubscribeHandler) {
self.subscribeHandler = subscribeHandler
}
public func subscribe(eventHandler: @escaping EventHandler) {
let observer = Observer(eventHandler: eventHandler)
self.subscribeHandler(observer)
}
}
func map(source: Observable, transform: @escaping (_ value: String) -> String) -> Observable {
return Observable({ (observer) in
let closure = {(value: String) -> Void in
let transformedValue = transform(value)
observer.next(value: transformedValue)
}
source.subscribe(eventHandler: closure)
})
}
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
print(value)
print(value)
}
map(source: observable) { (value) -> String in
return "hi " + value
}.subscribe(eventHandler: closure)
在 map 内部,根据外层传进来的闭包 transform 处理生成一个新的 Observable。
在新的 Observable 内部,创建一个闭包将 value 转换成 transformedValue,原始的 sourec 订阅这个闭包,当监听到外层数据传进来,通知内部 observer 进行更新。
本文 Demo:https://github.com/superzcj/RxSwiftDemo
总结
首先我们从理论上介绍了 RxSwift 基本原理,然后用 Swift 实现了 RxSwift 的基础:观察者模式,最后分别实现了 Observable、Observer 和 Operator。
以上都属于 RxSwift 的核心,我们完整实现一遍,相信在这个过程中,大家会对 RxSwift 有一个更深刻的认识,同时也能更好地运用 RxSwift 进行开发。
下一篇我们将介绍 RxSwift 如何结合 MVVM,更好地服务我们的业务开发。
网友评论