RxSwift
RxSwift中文解释
RxSwift Rx标准API的Swift实现 不包括任何iOS相关的内容
RxCocoa 基于RxSwift 给iOS UI控件扩展了很多Rx特性
RxSwift核心角色
Observable: 负责发送事件(Event)
Observer 负责订阅Observable 监听Observable发送的事件(Event)
Evenet类型
public enum Event {
case next(Element)
case error(Swift.Error)
case completed
}
next 携带具体数据
error 携带错误信息 表明Observable终止 不会再发出事件
completed 表明Observable终止 不会再发出事件
创建 订阅
let observable = Observable.create { (observer) -> Disposable in
observer.onNext(11)
observer.onNext(22)
observer.onNext(33)
//不再发送消息
observer.onCompleted()
return Disposables.create()
}
observable.subscribe { (event) in
switch event {
case .next(let element):
print(element)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
observable.subscribe(onNext: { (element) in
print(element)
}, onError: { (error) in
print(error)
}, onCompleted: {
print("completed")
})
发送消息
发送单条
//发送一个1 的消息 并且发送完成之后就结束了
let observable = Observable.just(1)
发送多条
let observable = Observable.of(1,2,3)
let observable = Observable.from([1,2,3])
from等价于of 把元素一个个的发送给去
let observable = Observable.just([1,2,3])
just会把整体作为一个元素发送过去
定时器
//2秒之后 每隔1秒的定时器 在主线程
let observable = Observable.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
//2秒之后 每隔1秒的定时器 在主线程
let observable = Observable.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
//绑定到label上面
observable.map {
"\($0)"
}.bind(to: label.rx.text)
Disposable
let disposable = observable.subscribe { (event) in
switch event {
case .next(let element):
print(element)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
//订阅之后 取消订阅 不会再接受事件
disposable.dispose()
//订阅之后 立即取消订阅
observable.map {
"\($0)"
}.bind(to: label.rx.text).dispose()
DisposeBag
当bag销毁的时候 会自动调用Disposable实例的dispose
let bag = DisposeBag()
observable.map {
"\($0)"
}.bind(to: label.rx.text).disposed(by: bag)
takeUntil
生命周期的管理 当控件释放的时候再取消订阅
let _ = observable.takeUntil(self.rx.deallocated).map {
"\($0)"
}.bind(to: label.rx.text)
创建Observer
let observer = AnyObserver.init { (event) in
switch event {
case .next(let element):
print(element)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
Observable.just(1).subscribe(observer).dispose()
//绑定到label
let binder = Binder.init(label) { (label, value) in
label.text = value
}
//发送订阅消息 改变label的text值
Observable.just(1).map {
"数组: \($0)"
}.subscribe(binder).dispose()
button 每一秒显示 消失
let observable = Observable.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
let binder = Binder(button) { button,value in
button.isHidden = value
}
observable.map { $0 % 2 == 0
}.bind(to: binder).disposed(by: bag)
let observable = Observable.timer(.seconds(2), period: .seconds(1), scheduler: MainScheduler.instance)
observable.map { $0 % 2 == 0
}.bind(to: button.rx.isHidden).disposed(by: bag)
RxSwift 的底层实现
extension Reactive where Base: UIControl {
var hidden: Binder {
return Binder(base) { button,value in
button.isHidden = value
}
}
var enabled: Binder {
return Binder(base) { button,value in
button.isEnabled = value
}
}
}
传统的状态监听
1.KVO
2.Target - Action
3.Notification
4.Delegate
5.Block Callback
会出现错综复杂的依赖关系 耦合性较高 需要编写重复的非业务代码
RxSwift的状态监听
Target - Action
button.rx.controlEvent(.touchUpInside).subscribe(onNext: {
print("按钮被点击了")
}).disposed(by: bag)
KVO
class Dog: NSObject {
@objc dynamic var name: String?
}
var dog = Dog();
dog.rx.observe(String.self,"name").subscribe(onNext: { (name) in
print("\(String(describing: name))")
}).disposed(by: bag)
dog.name = "larry"
dog.name = "wangw"
Notification
NotificationCenter.default.rx.notification(UIApplication.didEnterBackgroundNotification).subscribe(onNext: { notification in
print("进入后台")
}).disposed(by: bag)
即是Observable 又是observer
是 RxCocoa.ControlProperty 类型
//Observable
Observable.just(0.8).bind(to: slider.rx.value).disposed(by: bag)
//observer
slider.rx.value.map {
"数值是 \($0)"
}.bind(to: textField.rx.text).disposed(by: bag)
textField.rx.text.subscribe(onNext: { text in
print("\(String(describing: text))")
}).disposed(by: bag)
UITableView 的使用
persons.bind(to: tableView.rx.items(cellIdentifier: "cell")) {
row, person, cell in
cell.textLabel?.text = person.name
cell.detailTextLabel?.text = "\(person.age)"
}.disposed(by: bag)
tableView.rx.modelSelected(Person.self).subscribe(onNext: { person in
//
print(person)
}).disposed(by: bag)
tableView.rx.itemSelected.subscribe(onNext: { path in
print("点击了哪里",path)
}).disposed(by: bag)