Rx的核心内容是: 一个可观察序列(Observable) + 观察者(Observer) 被一个Disposable管理。 从这里我们可以看出只要创建了可观察者序列和观察者,那么就可以使用Rx思想来实现编码。
有个案例:登录界面的两个textfield通过rx思想实现了负责的业务,其中有一个是根据两个textfield的输入内容来控制登录btn的可点击状态。
有人就想问了,那如果我要控制登录btn的颜色可以实现吗? 答案是可以的,前提是要对Observer做一个小小的扩展。
extension Reactive where Base: UIView {
public var color: Binder<UIColor?> {
return Binder(self.base) { view, color in
view.backgroundColor = color
}
}
//创建textField文本 text 为序列
**let** text: Observable<String> = **self**.textFld.rx.text.orEmpty.asObservable()
//创建text长度校验 fldValid 为序列
**let** fldValid: Observable<Bool> = text.map { $0.count >= 5 }
//创建fldValid映射的颜色 outputColor 为序列 其实就是信息的转换(适合封装业务逻辑)
**let** outputColor: Observable<UIColor> = fldValid.map { $0 ? UIColor.red : UIColor.blue }
//创建btn的背景色为观察者 -- 因为框架没有实现,这里做了自定义扩展
**let** observer = rxBtn.rx.color
//管理订阅 -- 绑定序列和观察者
outputColor.bind(to: observer)
.disposed(by: disposeBag)
RxSwift的核心三步
- 创建可观察序列
- 创建观察者订阅序列
- 发送信号(给观察者)
RxSwift 核心代码分析
第一步 创建序列
let ob = Observable<Any>.create { observer in
return Disposables.create()
}
第二步 订阅信号
let _ = ob.subscribe { text in
print("订阅到了\(text)")
} onError: { error in
print("错误: \(error)")
} onCompleted: {
print("Done")
} onDisposed: {
print("disposed")
}
.disposed(by: disposeBag)
第三步 发送信号
let ob = Observable<Any>.create { observer in
//第三步发送信号
observer.onNext("onNext")
observer.onCompleted()
return Disposables.create()
}
上面的代码结果是打印了“订阅到了onNext”,结果是对了,但问题是在创建序列的闭包中发送信号为什么会在订阅的闭包中接收到呢??? 那我们就从源码中一探究竟吧。
Observable:
public class Observable<Element> : ObservableType {
public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
rxAbstractMethod()
}
public func asObservable() -> Observable<Element> { self }
}
asObservable, 转化为可观察序列,为万物皆可Rx提供了可能
Observable 创建
// 利用协议ObservableType 拓展的create方法实现,里面创建了一个 AnonymousObservable(匿名可观察序列)
extension ObservableType {
public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> {
AnonymousObservable(subscribe)
}
}
//AnonymousObservable -> 父类Producer 提供了subscribe 方法
final private class AnonymousObservable<Element>: Producer<Element> {
typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
let subscribeHandler: SubscribeHandler
init(_ subscribeHandler: @escaping SubscribeHandler) {
//保存这个subscribe闭包
self.subscribeHandler = subscribeHandler
}
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)//执行subscribe闭包
return (sink: sink, subscription: subscription)
}
}
再看观察者Observer
public func subscribe(
onNext: ((Element) -> Void)? = nil,
onError: ((Swift.Error) -> Void)? = nil,
onCompleted: (() -> Void)? = nil,
onDisposed: (() -> Void)? = nil
) -> Disposable {
let disposable: Disposable
//省略...
}
return Disposables.create(
//asObservable, 转化为可观察序列(Producer) 执行subscribe
self.asObservable().subscribe(observer),
disposable
)
}
Producer 执行run 就把观察者的闭包作为参数传入
class Producer<Element>: Observable<Element> {
override init() {
super.init()
}
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()
//Producer 的内部run只有抽象方法 其实真正实现的是它的子类AnonymousObservable
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
rxAbstractMethod()
}
}
AnonymousObservable 实现run方法
final private class AnonymousObservableSink<Observer: ObserverType>: Sink<Observer>, ObserverType {
typealias Element = Observer.Element
typealias Parent = AnonymousObservable<Element>
//省略...
func run(_ parent: Parent) -> Disposable {
//self即为创建序列create方法返回的observable对象,而_subscribeHandler是创建序列所保存的闭包,此时我们的闭包就被调用
parent.subscribeHandler(AnyObserver(self))
}
}
总结
1.创建序列时,创建一个_able闭包, 同时创建了AnonymousObservable实例_able,并保存闭包
2.订阅序列时,创建一个_ob闭包,同时创建了AnonymousObserver实例_ob,并保存闭包
3.创建一个AnonymousObservableSink实例sink,存储了_ob
4.sink执行run方法,调用了_able闭包, 同时创建一个AnyObserver实例anyOb
5.anyOb保存了sink的on方法
6.当_able闭包中发送信号,等于anyOb调用了on,最后回到_ob的onCore方法
7.执行onCore方法,就是执行_ob闭包,根据事件类型回调我们的订阅闭包