张科的技术博客

折腾是一种态度

嗨,我是张科(@GarfieldLover),搜狐视频iOS开发者。


这是我用来记录实践和填坑经验心得的地方,欢迎您的访问。


RxSwift

1.函数式编程是种编程范式,他是通过构建函数操作序列,然后对这些序列做出响应的编程方式,它结合了函数式编程以及响应式编程 2.函数式编程的优点

灵活 高复用 简洁 易维护 适应各种需求变化

3.我们通过不同的构建函数,来创建所需要的数据序列。最后通过适当的方式来响应这个序列。这就是函数响应式编程。 4.Observable是可监听序列,Observe是观察者,数据绑定(订阅,就是将可监听序列绑定到观察者上。 5.RxSwift核心内容

Observable - 产生事件 Observer - 响应事件 Operator - 创建变化组合事件 Disposable - 管理绑定(订阅)的生命周期 Schedulers - 线程队列调配

6.Observable - 可监听序列(万物皆序列)

Single 发出一个元素,或者一个 error 事件,不会共享附加作用 Completable 发出零个元素,发出一个 completed 事件或者一个 error 事件,不会共享附加作用 Maybe 发出一个元素或者一个 completed 事件或者一个 error 事件,不会共享附加作用 Driver 不会产生 error 事件,一定在 MainScheduler 监听(主线程监听),共享附加作用 Signal Signal 和 Driver 相似,唯一的区别是,Driver 会对新观察者回放(重新发送)上一个元素,而 Signal 不会对新观察者回放上一个元素。 ControlEvent 不会产生 error 事件,一定在 MainScheduler 订阅(主线程订阅),一定在 MainScheduler 监听(主线程监听)

7,Observer - 观察者是用来监听事件,然后它需要这个事件做出响应,响应事件的都是观察者

创建观察者最直接的方法就是在 Observable 的 subscribe 方法后面描述,事件发生时,需要如何做出响应。而观察者就是由后面的 onNext,onError,onCompleted的这些闭包构建出来的。 Binder 不会处理错误事件,确保绑定都是在给定 Scheduler 上执行(默认 MainScheduler) button.rx.isEnabled

extension Reactive where Base: UIControl { public var isEnabled: Binder { return Binder(self.base) { control, value in control.isEnabled = value } } } 复制代码

label.rx.text

extension Reactive where Base: UILabel { public var text: Binder<String?> { return Binder(self.base) { label, text in label.text = text } } } 复制代码 8.Observable & Observer 既是可监听序列也是观察者,例如:textField的当前文本。它可以看成是由用户输入,而产生的一个文本序列。也可以是由外部文本序列,来控制当前显示内容的观察者: // 作为可监听序列 let observable = textField.rx.text observable.subscribe(onNext: { text in show(text: text) }) 复制代码 // 作为观察者 let observer = textField.rx.text let text: Observable<String?> = … text.bind(to: observer) 复制代码 有许多 UI 控件都存在这种特性,例如:switch的开关状态,segmentedControl的选中索引号,datePicker的选中日期等等。

AsyncSubject 将在源 Observable 产生完成事件后,发出最后一个元素(仅仅只有最后一个元素),如果源 Observable 没有发出任何元素,只有一个完成事件。那 AsyncSubject 也只有一个完成事件。

let disposeBag = DisposeBag() let subject = AsyncSubject()

subject .subscribe { print(“Subscription: 1 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🐶”) subject.onNext(“🐱”) subject.onNext(“🐹”) subject.onCompleted() 复制代码 结果 Subscription: 1 Event: next(🐹) Subscription: 1 Event: completed 复制代码

PublishSubject 将对观察者发送订阅后产生的元素,而在订阅前发出的元素将不会发送给观察者。如果你希望观察者接收到所有的元素,你可以通过使用 Observable 的 create 方法来创建 Observable,或者使用 ReplaySubject。

let disposeBag = DisposeBag() let subject = PublishSubject()

subject .subscribe { print(“Subscription: 1 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🐶”) subject.onNext(“🐱”)

subject .subscribe { print(“Subscription: 2 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🅰️”) subject.onNext(“🅱️”) 复制代码 结果 Subscription: 1 Event: next(🐶) Subscription: 1 Event: next(🐱) Subscription: 1 Event: next(🅰️) Subscription: 2 Event: next(🅰️) Subscription: 1 Event: next(🅱️) Subscription: 2 Event: next(🅱️) 复制代码

ReplaySubject将对观察者发送全部的元素,无论观察者是何时进行订阅的。

这里存在多个版本的 ReplaySubject,有的只会将最新的 n 个元素发送给观察者,有的只会将限制时间段内最新的元素发送给观察者。 如果把 ReplaySubject 当作观察者来使用,注意不要在多个线程调用 onNext, onError 或 onCompleted。这样会导致无序调用,将造成意想不到的结果。 let disposeBag = DisposeBag() let subject = ReplaySubject.create(bufferSize: 1)//订阅前的缓存个数

subject .subscribe { print(“Subscription: 1 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🐶”) subject.onNext(“🐱”)

subject .subscribe { print(“Subscription: 2 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🅰️”) subject.onNext(“🅱️”) 复制代码 结果 Subscription: 1 Event: next(🐶) Subscription: 1 Event: next(🐱) Subscription: 2 Event: next(🐱) Subscription: 1 Event: next(🅰️) Subscription: 2 Event: next(🅰️) Subscription: 1 Event: next(🅱️) Subscription: 2 Event: next(🅱️) 复制代码

BehaviorSubject 当观察者对 BehaviorSubject 进行订阅时,它会将源 Observable 中最新的元素发送出来(如果不存在最新的元素,就发出默认元素)。然后将随后产生的元素发送出来. (订阅前的最新元素发出来)

let disposeBag = DisposeBag() let subject = BehaviorSubject(value: “🔴”)

subject .subscribe { print(“Subscription: 1 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🐶”) subject.onNext(“🐱”)

subject .subscribe { print(“Subscription: 2 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🅰️”) subject.onNext(“🅱️”)

subject .subscribe { print(“Subscription: 3 Event:”, $0) } .disposed(by: disposeBag)

subject.onNext(“🍐”) subject.onNext(“🍊”) 复制代码 结果 Subscription: 1 Event: next(🔴) Subscription: 1 Event: next(🐶) Subscription: 1 Event: next(🐱) Subscription: 2 Event: next(🐱) Subscription: 1 Event: next(🅰️) Subscription: 2 Event: next(🅰️) Subscription: 1 Event: next(🅱️) Subscription: 2 Event: next(🅱️) Subscription: 3 Event: next(🅱️) Subscription: 1 Event: next(🍐) Subscription: 2 Event: next(🍐) Subscription: 3 Event: next(🍐) Subscription: 1 Event: next(🍊) Subscription: 2 Event: next(🍊) Subscription: 3 Event: next(🍊) 复制代码

ControlProperty 专门用于描述 UI 控件属性的,它具有以下特征:

不会产生 error 事件一定在 MainScheduler 订阅(主线程订阅一定在 MainScheduler 监听(主线程监听)共享附加作用 9,RxSwift 认为不管是 Cold 还是 Hot,它们都是 Observable,它们同属于一个抽象,而不是两种独立的类型。这个观点很有意思,也就是说如果你自己声明了一个 Observable(遵守 ObservableType 协议),使用者并不知道它是 Cold 还是 Hot,只有你自己清楚,真正的“冷暖自知”。 Cold Observable只有在被订阅的时候才会发射事件,每次有新的订阅者都会把之前所有的事件都重新发射一遍; Hot Observable则是实时的,一旦有新的事件它就发射,不管有没有被订阅,而新的订阅者并不会接收到订阅前已经发射过的事件。