RxSwift的个人笔记
最近在看电报项目 https://github.com/TelegramMessenger/Telegram-iOS.git 发现里面也是使用响应式编程,里面SSignalKit库来做事件触发和监听相关的内容。由于原来主要是用Object-C开发,对于Swift的骚气用法老是消化不良,看了一段时间,有一些明白了些的点需要记录下来。
和RxSwift对比,个人觉得 SSignalKit 学习起来更好理解,看了一段时间,我发现了需要吐槽的点,RxSwift命名上面导致它不好吸收。
说明Single的两个主要方法(你会不会觉得SingleObserver应该换个名字,毕竟这不是用作观察者而是要主动发消息的):
// 用商家发货来举例, create是相当于定义了商品下单后的一些列流程。其中 SinglePoster 对象也就是 sendGoods 发货时执行的具体内容,业务侧通过SinglePoster来发货 public static func create(sendGoods: @escaping (@escaping SinglePoster) -> Disposable) -> Single<Element> { // 创建一个快递单,方法内给出一个闭包,让业务侧(商家)可以实现快递的发送(商家通过平台指定好的方式来发货) let goodsStream = Receiveable<Element>.create { poster in // 这里相当于创建了商品快递流,这个快递是通过快递员来送货的 // 这里平台定义商家发货的具体方式,通过sendGoods这个闭包,给到商家 return sendGoods { goods in switch goods { case .success(let box): poster.send(.next(box)) // 商品准备好了,让快递员送货 (送货实际上是快递员在执行这项操作) poster.send(.completed) // 快递员告知货物送达 case .failure(let error): poster.send(.error(error)) // 快递员告知快递单异常 } } } return PrimitiveSequence(raw: goodsStream) }
// 下单并且开始监听快递单的进程,此处 SingleEvent 相当于快递的变化情况, Element 是具体变化内容 public func subscribe(_ observer: @escaping (SingleEvent<Element>) -> Void) -> Disposable { var stopped = false return self.primitiveSequence.asObservable().subscribe { event in // 这里是将快递员送货情况,上报给平台转为快递单变化情况,通知给到购买者 if stopped { return } stopped = true switch event { case .next(let element): observer(.success(element)) // 订单完成,货物送达 case .error(let error): observer(.failure(error)) // 送货失败,订单异常 case .completed: rxFatalErrorInDebug("Singles can't emit a completion event") } } }
查看on方法顺着逻辑找到Observer对象:
这里Observer对象是在subscribe调用时创建的,创建时传入了一个闭包,这个闭包代表的就是监听到值改变时的响应处理 observer。同时 create 方法中使用到的 on 方法,也是通过这个对象来进行调用的。
/// A type-erased `ObserverType`. /// /// Forwards operations to an arbitrary underlying observer with the same `Element` type, hiding the specifics of the underlying observer type. public struct AnyObserver<Element> : ObserverType { /// Anonymous event handler type. public typealias EventHandler = (Event<Element>) -> Void private let observer: EventHandler /// Construct an instance whose `on(event)` calls `eventHandler(event)` /// /// - parameter eventHandler: Event handler that observes sequences events. public init(eventHandler: @escaping EventHandler) { self.observer = eventHandler } /// Construct an instance whose `on(event)` calls `observer.on(event)` /// /// - parameter observer: Observer that receives sequence events. public init<Observer: ObserverType>(_ observer: Observer) where Observer.Element == Element { self.observer = observer.on } /// Send `event` to this observer. /// /// - parameter event: Event instance. public func on(_ event: Event<Element>) { self.observer(event) } /// Erases type of observer and returns canonical observer. /// /// - returns: type erased observer. public func asObserver() -> AnyObserver<Element> { self } }
这里可以看到,调用 on 方法时,即调用了 observer 这个闭包。
注意:
1. 我们create的时候,只是定义了相关的逻辑(此时并没有进行真正的调用),相当于定义了 subscribe 之后会进行怎么样的处理
2. 当我们进行 subscribe 时,才会进行下单,此时开始执行我们在create时定义的逻辑,也就是说每次 subscribe 都会跑一遍这块代码。
3. 当我们调用 subscribe 时,才会生成 observer 对象(也是上面说的 poster 对象),这样才能使create内的代码逻辑正确执行。
以下是说明示例:
可以看出,同一个 Single 对象,调用两次 subscribe 是不同的。并且可以尝试不调用 subscribe 方法,那么 create 的函数体也不会执行,不会有任何打印。
Producer<Element>: Observable<Element> 实现 subscribe 方法,可订阅
Observer: ObserverType 实现 on 方法,可接收数据变化通知
Sink<Observer: ObserverType>: Disposable 持有 Observer 对象,给Observer对象传递消息,实现启动 (run方法)
创建 Producer 对象,定义好事务的逻辑
Producer 的 subscibe 方法传入 Observer 对象(Observer对象会持有收到消息后的逻辑处理闭包)。此时会调用 Producer 的 run 方法
Producer 的 run 方法(传入Observer对象)内部创建 Skin 对象,可以理解为一个具体的调控和执行者。
Sink 包装 Observer 对象,调用它自己的 run 方法,执行 Producer 创建时定义的函数闭包(传入可触发Observer对象 on 方法的对象),并且 Skin 的 on 方法实现了消息传递给到 Observer
将结束监听的方法调用,封装为 SinkDisposer 对象,包含了任务销毁涉及对象的相关的 dispose 方法调用
create等创建数据初始化和变化的逻辑,辅助一些过滤、转换的方法,在后面进行最终subscribe