学过 Swift 的 同窗都知道, RxSwift 宛如 周董的 mojitogit
开始微醺github
再者上头编程
为何要学习 RxSwift ?json
卡蜜尔说过api
优雅,永不过期
数组
RxSwift 是 Rx 系列的 Swift 版本,相较于 OC 版的 ReactiveCocoa安全
它们有着殊途同归之妙 函数响应式编程(FRP)
bash
什么是 函数响应式编程 ?markdown
函数式编程的核心思想是 stateless
,无状态。函数自己并不关心
外界输入的值网络
它只是在函数内部,将输入的值 和 输出的值 完成一种映射,即 input => output
好比:
func changeNum(input: Int) -> Int { return input * 3 } // changeNum 并不会对input 产生改变,只是将运算以后的值 输出 复制代码
无状态
意味着函数自己,不会改变外部的状态
,也不会改变输入的值的状态
Q
:将数组 [1,2,3,4] 里的元素 都乘以2,返回新的数组
那么通常的作法多是:
命令式编程
let array = [1,2,3,4] var newArray: [Int] = [] for item in array { var num = item num *= 2 newArray.append(num) } // [2,4,6,8] 复制代码
命令式编程倾向于怎么作
,具体是怎么把每一个数都 * 2 的,那么这里 涉及到了 可变数组 newArray
若是某一个时刻
,newArray 被某个地方
改变了,都会达到 非预期
的效果
那么函数式编程
会怎么作呢?
let array = [1,2,3,4] let newArray = array.compactMap { return $0 * 2 } // [2,4,6,8] 复制代码
函数式编程
和 申明式编程
的 思想大致一致
它们都只关注 作什么
,而不是上面的 怎么作?
函数式编程:倾向于作什么,省去其繁琐的过程,一种更为 安全,直观,易懂的编程方式
一种抽象的事件流
的异步编程
方法
好比
:用户点击一个按钮,发送网络请求,并将结果展现在label 上
这里网络请求是异步
的
想要展现在label 上,就要拿到 网络请求的回调,进一步展现
造成事件流
写法就是
button.rx.tap.subscribe(onNext: { // 点击按钮 HomeApi.getTitle().asObservable() // 发起网络请求 .map { (title) -> String in // 拿到回调进行 map ("我是 \(title)") } .bind(to: (titleLabel?.rx.text)!) // 绑定给 label .disposed(by: rx.disposeBag) // 管理生命周期 }) 复制代码
这么一个较为复杂的操做,且包含异步操做
的流程
在 RxSwift 的 调整以后,是否是更为 简单易懂
? 事件的分发以及维护,能够在一个地方完成
大大提升了 代码的可读性
,以及维护成本
整个事件流
的过程 以下:
咱们不用去关心
序列中的 每个元素,是异步的 仍是同步的,线程是否安全
只有当咱们点击按钮
,发送信号
以后 ,代码块内的函数体才会执行,整个一系列的事件流才会产生
这使得咱们更加面向业务逻辑
而不是每一步的具体操做
那么具体 RxSwift 是怎么作到的呢?
喝完 mojito
你就知道了
对于初学者来讲
RxSwift 的学习曲线确实很陡,它诠释了什么是面向协议编程
过程虽然晦涩
但道阻且长
真正的大师永远怀着一颗学徒的心
在RxSwift 的世界里,万物皆 rx,处处是 序列
(sequence)
听着像不像 iOS 的万物皆对象
是的没错,咱们来看一下rx Reactive
的定义,首先引入眼帘的是 一个 叫 ReactiveCompatible
的协议
public protocol ReactiveCompatible { # 关联协议 associatedtype ReactiveBase # rx 是 Reactive 类型,并将 ReactiveBase 传入 static var rx: Reactive<ReactiveBase>.Type { get set } var rx: Reactive<ReactiveBase> { get set } } 复制代码
Reactive 中 还对 ReactiveCompatible
进行了 协议的拓展,在这个扩展中,经过调用rx
,返回的是
Reactive 类型
或者Reactive实例
extension ReactiveCompatible { # Reactive 类型 public static var rx: Reactive<Self>.Type { get { return Reactive<Self>.self } } # Reactive 实例 public var rx: Reactive<Self> { get { return Reactive(self) } } } 复制代码
在看一下 Reactive
的 实现,是一个 包含参数泛型 Base
的结构体
public struct Reactive<Base> { public let base: Base # 将 Reactive 的初始化调用者 设置为 base public init(_ base: Base) { self.base = base } } 复制代码
如上文中 点击按钮的 tap,即 button.rx.tap
, 类型就是 UIButton 类型,将 UIButton 的实例 设置为 base
那么想 实现 万物皆rx
,只须要简单的一步
extension NSObject: ReactiveCompatible { }
复制代码
这样就可让全部继承于 NSObjce
的对象,都遵循 ReactiveCompatible
协议,即 万物皆rx
Observable 意味着,可被观察的,也就是可观察序列
,什么是序列呢?
我理解的就是 具有 发出事件能力的 的一种信号
肚子饿了 -> 吃饭
肚子饿了
能够做为一个 可观察序列,当咱们大脑感知到 肚子饿了,就能够执行 去吃饭的操做
TextField 输入 -> 显示
TextField 输入操做
能够做为一个序列,能够监听到 输入的内容
接下来
就开始调试 mojito 了
看一个订阅过程:
# 建立 let observable = Observable<String>.create { (observe) -> Disposable in # 发送 observe.onNext("mojito") return Disposables.create() } # 订阅 observable.subscribe(onNext: { text in print(text) }).disposed(by: rx.disposeBag) // print "mojito" 复制代码
Observable 可观察序列
# Observable 继承于 ObservableType public class Observable<Element> : ObservableType { # 资源的引用计数 +1 init() { _ = Resources.incrementTotal() } # 提供被订阅的能力,由子类实现 public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element { rxAbstractMethod() } # 将 Observable 类转为 Observable 实例 public func asObservable() -> Observable<Element> { return self } # 资源的引用计数 -1 deinit { _ = Resources.decrementTotal() } } 复制代码
但是这里并无看到序列的建立
,可是能够看到一个 继承关系: Observable<Element> : ObservableType
进入 ObservableType
# 协议 ObservableType,继承于 ObservableConvertibleType public protocol ObservableType: ObservableConvertibleType { func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element } # ObservableType 扩展 extension ObservableType { # 提供了一个方法,将遵照 ObservableType 协议的对象 转为 Observable 实体 public func asObservable() -> Observable<Element> { return Observable.create { o in return self.subscribe(o) } } } 复制代码
这里仍是 没有看到 订阅的方法
还发现了 本身的爸爸是个协议
, 还有爷爷 ObservableConvertibleType
持着怀疑的态度,你又点进了 ObservableConvertibleType
# 也是个协议 public protocol ObservableConvertibleType { associatedtype Element typealias E = Element # 定义了一个方法,返回类型 Observable 可观察序列 func asObservable() -> Observable<Element> } 复制代码
可恶
既然这条路走不通,只能先不走了
哪里跌倒
我就躺在哪里
为了达到万物皆序列,咱们就要想办法把全部事件转化为序列,asObservable() 即为 RxSwift 的精髓
Observable.create()
点击 creat ,豁然开朗,原来建立是经过 ObservableType
扩展,这也同时证实了 OOP
的好处,可扩展性强
ObservableType
像是一家名叫 ObservableType 的连锁公司
它能够在任何地方开个分店
实现本身公司的业务
# ObservableType 的扩展 extension ObservableType { public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> { # 返回一个 匿名观察序列,将 subscribe 逃逸闭包传入 return AnonymousObservable(subscribe) } } 复制代码
点击 AnonymousObservable 进入
# 私有方法,外界没法共享 # AnonymousObservable 继承于 Producer final private class AnonymousObservable<Element>: Producer<Element> { typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable # 定义 闭包属性 let _subscribeHandler: SubscribeHandler # 将外界传入的 闭包 保存 init(_ subscribeHandler: @escaping SubscribeHandler) { self._subscribeHandler = subscribeHandler } # 重写 父类 Producer 提供的 run 方法 override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { # 初始化匿名管道,传入一个订阅者 let sink = AnonymousObservableSink(observer: observer, cancel: cancel) let subscription = sink.run(self) return (sink: sink, subscription: subscription) } } 复制代码
这里又来了个 Producer
,点击 Producer
# Producer 一样继承于 Observable class Producer<Element> : Observable<Element> { override init() { super.init() } # 这里涉及到了线程,若是 CurrentThreadScheduler 指定了某个线程,那么就会在指定线程中 执行 run # 不然 就会在当前线程中 执行 run # SinkDisposer实例 disposer,用来管理资源释放 override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element { if !CurrentThreadScheduler.isScheduleRequired { // The returned disposable needs to release all references once it was disposed. let disposer = SinkDisposer() let sinkAndSubscription = self.run(observer, cancel: disposer) disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription) return disposer } else { 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 } } } # 抽象方法,子类去实现,也就是匿名序列 AnonymousObservable func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { rxAbstractMethod() } } 复制代码
相信到此,你我都已经微醺了
你问我什么是 序列
?
我 指 着 大 海 的 方 向
目前也只能先画个图,继续观望
小结
父类协议
的 creat 方法 ,生成 匿名观察序列,即Producer
的子类AnonymousObservable
AnonymousObservable
保存外界传入的 闭包Observable
抽象类,不实现方法Producer
类 实现 外界 subscribe 方法,并安排线程调度run
,由 AnonymousObservable
实现,父类 Producer
不负责ok ,继续往下走
subscribe(onNext:) 订阅
点击 subscribe 进入,能够看到 ObservableType 的扩展,提供了 subscribe.on
和 subscribe.onNext
2个方法
此处省略了 subscribe.on
extension ObservableType { ... public func subscribe(onNext: ((Element) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil) -> Disposable { .... # 建立一个 匿名订阅者 AnonymousObserver # 对外界传入的执行闭包 进行保存 let observer = AnonymousObserver<Element> { 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 ) } } 复制代码
这里将 外界须要执行的 闭包,即本例中的 print(text)
,生成 AnonymousObserver
实例,传入
self.asObservable().subscribe(observer)
也就是说,这个 AnonymousObserver
实例,会经过 Producer 调用 subscribe
而后由 子类 AnonymousObservable
,序列实例去调用 run
方法
来到文中,step 5 的 run
方法,以下
# 将外界 须要执行的闭包 ,以及 资源销毁实例 生成的 元祖 传入 AnonymousObservableSink # 生成 sink 管道实例,并执行 run # 将run 以后生成的实例,赋值给 subscription,并返回 subscription 和 sink override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { let sink = AnonymousObservableSink(observer: observer, cancel: cancel) let subscription = sink.run(self) return (sink: sink, subscription: subscription) } 复制代码
进入 AnonymousObservableSink
final private class AnonymousObservableSink<Observer: ObserverType>: Sink<Observer>, ObserverType { typealias Element = Observer.Element typealias Parent = AnonymousObservable<Element> # 调用父类 Sink 的初始化方法,传入 observer 和 cancel,即 管道 AnonymousObservableSink 持有 这2个属性 override init(observer: Observer, cancel: Cancelable) { super.init(observer: observer, cancel: cancel) } func on(_ event: Event<Element>) { 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() } } } ### 熟悉的东西有没有 # 这里看到了 _subscribeHandler,也就是 发出的信号,保存的闭包 func run(_ parent: Parent) -> Disposable { return parent._subscribeHandler(AnyObserver(self)) } } 复制代码
到这里,咱们就会发现 sink
管道 它很重要
它持有了
要销毁的实例,发出序列的闭包,执行序列的闭包
这里的 AnyObserver(self) 是为了 兼容传入 闭包的类型, 本文对应的 是 String
复制代码
那么 火车序列 就开始发动了
,可是 怎么响应? 下一步往哪开?
这就要看 AnyObserver(self)
,作了什么,进入 AnyObserver, 查看init
public init<Observer: ObserverType>(_ observer: Observer) where Observer.Element == Element { self.observer = observer.on } 复制代码
你会发现这里的 self.observer
保存了 本身的 on 方法
也就是保存的了一个 function
即 会调用 step8 中 的 on
, 而后 去调用 父类Sink 的 forwardOn
# 父类 Sink class Sink<Observer: ObserverType> : Disposable { final func forwardOn(_ event: Event<Observer.Element>) { #if DEBUG self._synchronizationTracker.register(synchronizationErrorMessage: .default) defer { self._synchronizationTracker.unregister() } #endif if isFlagSet(self._disposed, 1) { return } # 订阅者 self._observer.on(event) } } 复制代码
在父类 forwardOn
中, 由订阅者执行 on
事件
但是 订阅者 AnonymousObserver
类有没有 on
方法,只有 onCore
因此去 AnonymousObserver 的 父类中 ObserverBase
寻找
class ObserverBase<Element> : Disposable, ObserverType { private let _isStopped = AtomicInt(0) func on(_ event: Event<Element>) { switch event { case .next: if load(self._isStopped) == 0 { self.onCore(event) } case .error, .completed: if fetchOr(self._isStopped, 1) == 0 { self.onCore(event) } } } # 子类实现 func onCore(_ event: Event<Element>) { rxAbstractMethod() } } 复制代码
最后 AnonymousObserver
调用本身的 onCore
执行 eventHandler
闭包
到此
整个执行的过程算是走完了
关于资源回收
的内容,后续文章会写到
mojito 初体验 结束
AnonymousObservable
保存 可观察序列AnonymousObserve
保存 执行闭包SinkDisposer
以及 observer
实例 元祖Sink
管道Sink
处理事件,发出信号,响应序列简单的流程图以下
有了RxSwift ,平常开发就变得酣畅淋漓了,好比
tableView.rx.contentOffset.subscribe(onNext: { contentOffset in /// 修改透明度 }) .disposed(by: rx.disposeBag) 复制代码
textField.rx.text.skip(1).subscribe(onNext: { (text) in print("输入的是 : \(text!)") }) .disposed(by: rx.disposeBag) 复制代码
self.messageBtn.rx.tap.subscribe(onNext: { in Navigator.push("") }) .disposed(by: rx.disposeBag) 复制代码
# 这里须要导入 RxDataSources dataSource = RxTableViewSectionedReloadDataSource(configureCell: { (_, tab, indexPath, item) -> UITableViewCell in let cell = tab.dequeue(Reusable.settingCell, for: indexPath) cell.bind(to: item) return cell }) # 或者 let items = Observable.just([ "Just", "Relay", "From", "Driver", "merge" ]) items.bind(to: tableView.rx.items) { (tableView,_,element) in let cell = self.tableView.dequeue(TestV.normalCell) cell?.textLabel?.text = element return cell! } .disposed(by: rx.disposeBag) 复制代码
tableView.rx.itemSelected.subscribe(onNext: { indexPath in /// doSomething }) .disposed(by: rx.disposeBag) 复制代码
extension Response { func mapHandyJsonModel<T: HandyJSON>(_ type: T.Type) -> T { let jsonString = String.init(data: data, encoding: .utf8) if let modelT = JSONDeserializer<T>.deserializeFrom(json: jsonString) { return modelT } return JSONDeserializer<T>.deserializeFrom(json: "{\"msg\":\"解析有误\"}")! } } extension ObservableType where Element == Response { /// 注释 public func mapHandyJsonModel<T: HandyJSON>(_ type: T.Type) -> Observable<T> { return flatMap { response -> Observable<T> in return Observable.just(response.mapHandyJsonModel(T.self)) } } } # 配合 Moya static func getTopList() -> Observable<HomeResponseModel> { return HomeApiProvider.rx.request(.Top).asObservable().mapHandyJsonModel(HomeResponseModel.self) } 复制代码
Observable.zip(HomeApi.getTopList(), HomeApi.getRecommondList()).subscribe(onNext: { topResponse, recommodResponse in /// 数据处理 }).disposed(by: self.rx.disposeBag) 复制代码
先介绍一点简单的用法
后续会慢慢更新
RxSwift
熟悉了以后,会让咱们的代码变得 简洁且优雅
它面向协议编程,咱们面向业务编程
RxSwift
须要慢慢品味
听一遍 mojito
确定是不够的
不说了
听歌去了~
没喝过 mojito
的 就从这里开始吧~