响应式编程
响应式编程
(Reactive Programming),简称RP
,是一种面向数据流和变化传播的编程范式,可以简化异步编程,提供更优雅的数据绑定(举个不恰当的例子,有点类似于vue或者是react当中state发生变化时可以及时的更新UI)。
在swift
当中比较著名成熟的框架有两个
- ReactiveCocoa
官网: https://reactivecocoa.io/
github: https://github.com/ReactiveCocoa/ReactiveCocoa/ - ReactiveX
官网: http://reactivex.io/
github: https://github.com/ReactiveX/RxSwift
RxSwift
RxSwift
(reactive for swift), ReactiveX的swift版本
源码:https://github.com/ReactiveX/RxSwift
中文文档:https://beeth0ven.github.io/RxSwift-Chinese-Documentation/
RxSwift的核心角色
- Observable 负责发送事件(Event)
- Observer 负责订阅Observable,监听Observable发送的事件(Event)
RxSwift
源码(Event.swift)关于Event
描述如下
/// Represents a sequence event.
///
/// Sequence grammar:
/// **next\* (error | completed)**
public enum Event<Element> {
/// Next element is produced.
case next(Element)
/// Sequence terminated with an error.
case error(Swift.Error)
/// Sequence completed successfully.
case completed
}
所以,Event
有3种
next
: 携带具体的数据error
: 携带错误信息,表明Observable终止,不会再发出事件completed
: 表明Observable终止,不会再发出事件
创建Observable
override func viewDidLoad() {
super.viewDidLoad()
// 发消息
let observable = Observable<Int>.create { (observer) -> Disposable in
observer.onNext(123) // 发送了123消息
return Disposables.create()
}
// 也可以采用这种方式发送订阅消息,代表只发送一个1,然后就结束
// Observable.just(1)
// 这种方式代表发送三次,分别是1、2、3,然后结束
// Observable.from([1,2,3])
// 订阅
observable.subscribe { (event) in
switch event {
case .next(let element):
print("element:", element)
case .error(let error):
print("error:", error)
case .completed:
print("completed")
}
}
// 第二种订阅方式
observable.subscribe { (element) in
} onError: { (error) in
} onCompleted: {
} onDisposed: {
}
}
比如我们在做控件开发的时候,需要将一个定时器的的值显示在label
上面:
// 代表两秒之后,每隔一秒执行一次
let observable = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
// 绑定到控件上面
observable.map{"text:\($0)"}.bind(to: label.rx.text)
Disposables
每当Observable
被订阅的时候都会返回一个Observable
的实例,调用Observable
的dispose
就相当于取消订阅
// 代表两秒之后,每隔一秒执行一次
let observable = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
// 绑定到控件上面
let observer = observable.map{"text:\($0)"}.bind(to: label.rx.text)
observer.dispose()
对于取消订阅,有以下几种方式
- 立即取消订阅
// 订阅方法之后紧跟着dispose方法取消订阅 observable.subscribe { (event) in print(event) }.dispose()
- 当bag(被控制器或者其他对象持有)销毁(deinit)时,会自动调用Disposables实例的dispose
let bag = DisposeBag(); observable.subscribe { (event) in print(event) }.disposed(by: bag)
- 代表这一个订阅会跟随控制器的生命周期
observable.takeUntil(self.rx.deallocated).map{"\($0)"}.bind(to: label.rx.text)
传统状态监听方式
传统的监听方案:
- KVO
- Target-Action
- Notification
- delegate
- Block / Callback
传统方案通常会出现错综复杂的依赖关系,耦合性比较高,
比如我们现在需要做一个按钮的点击
, 传统方案的实现方式:
button.addTarget(self, action: #selector(buttonClick(_:)), for: .touchUpInside);
新的实现方案是:
button.rx.controlEvent(.touchUpInside).subscribe(onNext: {
print("按钮被点击了")
}).disposed(by: bag)
还有比如我们在做网络请求的时候,model
有变化的时候需要刷新界面,这时候通过RxSwift
状态监听实现,就非常方便了
class Dog: NSObject {
@objc dynamic var name: String?
}
let dog = Dog()
dog.rx.observe(String.self, "name").subscribe { (name) in
print(name)
}
dog.name = "dog"
本文首次发布于 孙忠良 Blog, 作者 [@sunzhongliang] , 转载请保留原文链接.