目录
响应式编程
一、响应式编程
响应式编程(Reactive Programming,简称RP)
也是一种编程范式,于1997年提出,可以简化异步编程,提供更优雅的数据绑定
一般与函数式融合在一起,所以也会叫做:函数响应式编程(Functional Reactive Programming,简称FRP)
比较著名的、成熟的响应式框架
ReactiveCocoa
简称RAC,有Objective-C、Swift版本
官网: http://reactivecocoa.io/
github:https://github.com/ReactiveCocoa
ReactiveX
简称Rx,有众多编程语言的版本,比如RxJava、RxKotlin、RxJS、RxCpp、RxPHP、RxGo、RxSwift等等
官网: http://reactivex.io/
github: https://github.com/ReactiveX
二、RXSwift
RxSwift(ReactiveX for Swift),ReactiveX的Swift版本
源码:https://github.com/ReactiveX/RxSwift
中文文档: https://beeth0ven.github.io/RxSwift-Chinese-Documentation/
RxSwift的github上已经有详细的安装教程,这里只演示CocoaPods方式的安装
① Podfile
use_frameworks!
target 'target_name' do
pod 'RxSwift', '~> 5'
pod 'RxCocoa', '~> 5'
end
② 命令行
pod repo update
pod install
③ 导入模块
import RxSwift
import RxCocoa
模块说明
RxSwift:Rx标准API的Swift实现,不包括任何iOS相关的内容
RxCocoa:基于RxSwift,给iOS UI控件扩展了很多Rx特性
三、RxSwift的核心角色
Observable:负责发送事件(Event)
Observer:负责订阅Observable,监听Observable发送的事件(Event)
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终止,不会再发出事件
四、传统的状态监听
在开发中经常要对各种状态进行监听,传统的常见监听方案有
KVO
Target-Action
Notification
Delegate
Block Callback
传统方案经常会出现错综复杂的依赖关系、耦合性较高,还需要编写重复的非业务代码
代码
import UIKit
import RxSwift
import RxCocoa
extension Reactive where Base : UIControl {
var hidden : Binder<Bool>{
Binder<Bool>.init(base) { (control, value) in
control.isHidden = value
}
}
var enable : Binder<Bool>{
Binder<Bool>(base) { (control, value) in
control.isEnabled = value
}
}
}
class LCRXSwiftViewController: UIViewController {
enum LCError:Error {
case Test
}
let bag = DisposeBag()
var label:UILabel!
var button:UIButton!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var slider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
title = "RXSwiftViewController"
addLabel()
addButton()
// showRXSwiftUse1()
// showRXSwiftUse2()
// showRXSwiftUse3()
// showRXSwiftUse4()
// showRXSwiftUse5()
// showRXSwiftUse6()
// showRXSwiftUse7()
// showRXSwiftUse8()
// showRXSwiftUse9()
showRXSwiftUse10()
}
//创建一个label
func addLabel() -> Void {
label = UILabel(frame: CGRect(x: 20, y: 100, width: 100, height: 80))
label.backgroundColor = UIColor.green
view.addSubview(label)
}
func addButton() -> Void {
button = UIButton(frame: CGRect(x: 140, y: 100, width: 100, height: 80))
button.backgroundColor = UIColor.blue
button.setTitleColor(UIColor.gray, for: UIControl.State.disabled)
button.setTitleColor(UIColor.blue, for: UIControl.State.normal)
view.addSubview(button)
}
//MARK: - 一、发送事件、订阅事件1
func showRXSwiftUse1() -> Void {
//
let observable = Observable<Int>.create { (observer:AnyObserver<Int>) -> Disposable in
observer.onNext(11)
observer.onError(LCError.Test)//会终止不会再发出事件
observer.onNext(22)
observer.onCompleted()//会终止不会再发出事件
observer.onNext(33)
return Disposables.create()
}
//
let _ = observable.subscribe { (event:Event<Int>) in
switch event {
case .next(let element):
print("element:",element)
case .error(let error):
print("error:",error)
case .completed:
print("completed")
}
}
//可以被多次订阅
let _ = observable.subscribe { (event:Event<Int>) in
switch event {
case .next(let element):
print("element:",element)
case .error(let error):
print("error:",error)
case .completed:
print("completed")
}
}
//另外一种订阅形式
let _ = observable.subscribe { (element:Int) in
print("element:",element)
} onError: { (error:Error) in
print("error:",error)
} onCompleted: {
print("completed")
} onDisposed: {
print("onDisposed")
}
}
//MARK: - 二、发送事件、订阅事件2
func showRXSwiftUse2() -> Void {
/**
相当于:
Observable<Int>.create { (observer) -> Disposable in
observer.onNext(1)
observer.onCompleted()
return Disposables.create()
}
*/
//let observable = Observable.just(1)
// let observable = Observable.of(1,2,3)
// let observable = Observable.from([1,2,3])
let observable = Observable<Int>.timer(.seconds(2), //2秒后
period: .seconds(1), //每隔1秒
scheduler: MainScheduler.instance)//主线程
//返回一个Disposable
let _ = observable.subscribe { (element) in
print("element:",element)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("completed")
} onDisposed: {
print("onDisposed")
}
//绑定到一个label上,也是订阅
let _ = observable.map{"数值是:\($0)"}.bind(to: label.rx.text)
}
//MARK: - 三、取消订阅的方式
func showRXSwiftUse3() -> Void {
/**
每当Observable被订阅时,都会返回一个Disposable实例,当调用Disposable的dispose,就相当于取消订阅
在不需要再接收事件时,建议取消订阅,释放资源。有3种常见方式取消订阅
// 立即取消订阅(一次性订阅)
observable.subscribe { event in
print(event)
}.dispose()
// 当bag销毁(deinit)时,会自动调用Disposable实例的dispose
observable.subscribe { event in
print(event)
}.disposed(by: bag)
// self销毁时(deinit)时,会自动调用Disposable实例的dispose
let _ = observable.takeUntil(self.rx.deallocated).subscribe { event in
print(event)
}
*/
let observable = Observable<Int>.timer(.seconds(3),
period: .seconds(1),
scheduler: MainScheduler.instance)
let disposable:Disposable = observable.subscribe { (element) in
print("element:",element)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("completed")
} onDisposed: {
print("onDisposed")
}
print(disposable)
//在某个特定的时刻取消订阅
//disposable.dispose()
//只订阅一次
observable.subscribe { (element) in
print("element:",element)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("completed")
} onDisposed: {
print("onDisposed")
}.dispose()
//bag销毁时调用dispose
observable.subscribe { (element) in
print("element:",element)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("completed")
} onDisposed: {
print("onDisposed")
}.disposed(by: bag)
//直到self销毁时取消订阅
let _ = observable
.take(until:self.rx.deallocated)
.map { "数值是:\($0)"}
.bind(to: label.rx.text)
}
//MARK: - 四、创建Observer
func showRXSwiftUse4() -> Void {
let observer = AnyObserver<Int>.init { (event) in
switch event {
case .next(let data):
print(data)
case .completed:
print("completed")
case .error(let error):
print(error)
}
}
Observable.just(1).subscribe(observer).dispose()
}
//MARK: - 五、Binder label
func showRXSwiftUse5() -> Void {
let binder = Binder<String>(label) { (label, value) in
print("value:",value)
label.text = value
}
//以下写法等价
Observable.of(1,2).map{"数值是:\($0)"}.subscribe(binder).dispose()
Observable.just(3).map {"数值是:\($0)"}.bind(to: binder).dispose()
Observable.just(4).map {"数值是:\($0)"}.bind(to: label.rx.text).dispose()
}
//MARK: - 六、Binder2 button
func showRXSwiftUse6() -> Void {
let observable = Observable<Int>.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.init())
/**
let binder = Binder<Bool>(label) { (label, value) in
label.isHidden = value
}
observable.map { $0 % 2 == 0}.bind(to: binder).disposed(by: bag)
*/
//通过扩展Reactive 可以简化成下面这样
//observable.map{ $0%2 == 0 }.bind(to: button.rx.hidden).disposed(by: bag)
//绑定enable属性
//observable.map{$0%2 == 0}.bind(to: button.rx.enable).disposed(by: bag)
//其实系统已经帮我们实现好了
observable.map{$0%2 == 0}.bind(to: button.rx.isHidden).disposed(by: bag)
}
//MARK: - 七、Binder3 button点击事件
func showRXSwiftUse7() -> Void {
//observable
let observable = button.rx.tap.map { "按钮事件:\($0)"}
//observer
let _ = observable.subscribe { (event) in
print(event)
} onError: { (error) in
print(error)
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("onDisposed")
}
}
//MARK: - 八、binder4 tableview
func showRXSwiftUse8() -> Void {
//Observable
let data = Observable.just([
LCPerson(name: "Jack", age: 10),
LCPerson(name: "Rose", age: 20)
])
//Observer
data.bind(to: tableView.rx.items(cellIdentifier: "rxcellid")){
row,person,cell in
cell.textLabel?.text = "\(row) " + person.name
cell.detailTextLabel?.text = "\(person.age)"
}.disposed(by: bag)
let _ = tableView.rx.modelSelected(LCPerson.self)
.subscribe { (person) in
print("点击了",person.name)
} onError: { (error) in
print("error",error)
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("onCompleted")
}
}
//MARK: - 九、binder5
func showRXSwiftUse9() -> Void {
//kvo
let _ = label.rx.observe(String.self,"text")
.subscribe { (text) in
print("text:",text as Any)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("onDisposed")
}
label.text = "哈哈"
//notification
NotificationCenter.default.rx.notification(UIApplication.didEnterBackgroundNotification)
.subscribe { (notification) in
print("App进入后台",notification)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("onDisposed")
}.disposed(by: bag)
}
//MARK: - 十、binder6
func showRXSwiftUse10() -> Void {
//既是Observable 又是 observer
//slider.rx.value 作为observer
Observable.just(0.8).bind(to: slider.rx.value).dispose()
//slider.rx.value 作为 observable
//textField.rx.text 作为observer
slider.rx.value.map{"当前数值是:\($0)"}
.bind(to: textField.rx.text).disposed(by: bag)
//textField.rx.text 作为observable
textField.rx.text.subscribe { (text) in
print("text:",text as Any)
} onError: { (error) in
print("error:",error)
} onCompleted: {
print("onCompleted")
} onDisposed: {
print("onDisposed")
}
/**
诸如UISlider.rx.value、UTextField.rx.text这类属性值,既是Observable,又是Observer
它们是RxCocoa.ControlProperty类型
*/
}
}
行者常至,为者常成!