- RxSwift 使用需要导入
import RxSwift
和import RxCocoa
,RxSwift
是基础库,RxCocoa
对我们Foundation
中的常用组件的监听帮我们做了扩展,如果不用RxCocoa
的话,我们想要监听这些控件的属性时,需要自己做很多的东西。
常用方式简单体验
- 常用方式一: 监听按钮的点击事件
testBtn.rx.tap.subscribe{ (event : Event<()>) in
print("按钮发生了点击");
}
对于订阅事件需要返回值,而我们没有写返回值的警告
,我们可以定义一个 DisposeBag
的变量来,并添加到订阅后来解决, 比如上面的代码我们只做了打印,并没有返回值,这是会有个警告提示,那么我们就可以通过这种方式解决
fileprivate lazy var bag: DisposeBag = DisposeBag()
testBtn.rx.tap.subscribe{ (event : Event<()>) in
print("按钮 1 发生了点击");
}.addDisposeableTo(bag)
对于使用 RxSwift 中没提示的问题
,可以先定义一个局部变量,使用局部变量将方法点出来之后再复制,比如上面的代码testBtn1.rx.tap.
的时候点不出来了,就可以定义一个局部变量let btn = UIButton()
,使用 btn.rx.tap.
出来要用的方法,然后复制粘贴
- 常用方式二: 订阅 TextField 文字的改变
textField.rx.text.subscribe{ (event : Event<String ?>) in
print(event.element!!) // 这里 event 是一个 Next 值
}.addDisposeableTo(bag)
// 或者
textField.rx.text.subscribe( onNext: {(str: String? ) in
print(str!)
}).addDisposeableTo(bag)
- 常用方式三: 将 textField 的text值绑定到一个 Lable 上
textField.rx.text.bindTo(textLable1.rx.text).addDisposeableTo(bag)
- 常用方式四: 监听Lable 的text的变化
testLabel.rx.observe(String.self, "text").subscribe(onNext:{(str: String?) in
print(str!)
}).addDisposeableTo(bag)
- 常用方式五: 监听 ScrollView 的滚动
scrollView.contentSize = CGSize(width: 10000, height: 200)
scrollView.rx.contentOffset.subscribe(onNext:{(point: CGPoint) in
print(point)
}).addDisposeableTo(bag)
常见操作
- never: 创建一个从来都不执行的 Observable, 不理解为啥既然重来都不执行了还要创建这个东西干嘛?
let never = Observable<String>.never()
never.subscribe{(event : Event<String>) in
print(event)
}.addDisposeableTo(bag)
- empty: 创建一个 empty Observable, empty 就是一个空的 sequence,只能发出一个 completed 的事件
let empty = Observable<String>.empty()
empty.subscribe{(event : Event<String>) in
print(event) // 这里会打印一次 completed 事件
}.addDisposeableTo(bag)
- just: 创建一个只能发出一种特定的事件,能正常结束
let just = Observable.just("张三")
just.subscribe{(event : Event<String>) in
print(event) // 这里会打印两次,一次 Next 事件,一次 completed 事件
}.addDisposeableTo(bag)
- of : 创建一个sequence 能发出很多种事件信号,并正常结束
let oftest = Observable.of("a","b","c","d")
oftest.subscribe{(event : Event<String>) in
print(event) // 这里会打印五次,四次 Next 事件一次输出a,b,c,d 和 一次 completed 事件
}.addDisposeableTo(bag)
- from: 从数组中创建 sequence
let fromtest = Observable.from([1,2,3,4])
fromtest.subscribe{(event : Event<Int>) in
print(event) // 这里会打印五次,四次 Next 事件一次输出1,2,3,4 和 一次 completed 事件
}.addDisposeableTo(bag)
- create: create 可以自定义可观察的 sequence, 需要传入一个观察者 observer,然后调用 observer 的 onNext, onCompleted 和 onError 方法,返回一个可观察的 obserable 序列
let create = Observable.create({(observer : AnyObserver<Any>) -> Disposable in
observer.onNext("zhangsan")
observer.onNext(18)
observer.onNext(1.8)
observer.onCompleted()
return Disposable.create()
})
- range
let range = Observable.range(start:1, count:10)
range.subscribe{(event : Event<Int>) in
print(event) // 这里会打印十一次,十次 Next 事件,一次 completed 事件
}.addDisposeableTo(bag)
- repeatElement
let repeat = Observable.repeatElement("hello world")
repeat.subscribe{(event : Event<String>) in
print(event) // 这里会一直重复打印next 事件 next(hello world)
}.addDisposeableTo(bag)
// 如果需要执行次数,需要先使用 repeat.take(count: Int) 方法指定次数
repeat.take(4).subscribe{(event : Event<String>) in
print(event) // 这里会一直重复打印next 事件 next(hello world)
}.addDisposeableTo(bag)
Subjects
- subjects 是 Observable 和Observer 之间的桥梁,一个 Subject 既是一个 Observable 也是一个 Observer,它既可以发出事件,也可以监听事件
- PublishSubject: 当你订阅 PublishSubject 的时候,你只能收到订阅它之后发生的事件。subject.onNext()发出 onNext 事件,对应的 onError() 和 onCompleted()事件
let publishSubject = PublishSubject<String>()
publishSubject.onNext("18"); // 发送的这个 onNext 事件,下面的订阅收不到,因为发生在订阅之前
publishSubject.subscribe{(event : Event<String>) in
print(event)
}.addDisposeableTo(bag)
publishSubject.onNext("张三");
- ReplaySubject: 当你订阅 ReplaySubject 的时候,你可以接收到订阅它之后的事件,也可以接收到订阅它之前发出的事件,接收几个事件取决与 bufferSize 的大小
let replaySubject = ReplaySubject<String>.create(bufferSize:2)
replaySubject.onNext("a");
replaySubject.onNext("b");
replaySubject.onNext("c");
replaySubject.subscribe{(event : Event<String>) in
print(event) // 会接受到 b,c,d
}.addDisposeableTo(bag)
replaySubject.onNext("d");
- BehaviorSubject, 订阅者可以接受,订阅之前的最后一个事件
let behaviorSub = BehaviorSubject(value:"a")
behaviorSub.onNext("b");
behaviorSub.onNext("c");
behaviorSub.onNext("d");
behaviorSub.subscribe{(event : Event<String>) in
print(event) // 会接收到 d,e,f,g
}.addDisposeableTo(bag)
behaviorSub.onNext("e");
behaviorSub.onNext("f");
behaviorSub.onNext("g");
- Variable: Variable 是 BehaviorSubject 的一个包装箱,使用的时候需要调用 asObservable()拆箱,里面的 value 是一个 BehaviorSubject, 如果要发出事件,直接修改对象的 value 即可,他不会发出 error 事件,但是会自动发出 completed 事件
let variable = Variable("a")
variable.asObserver().subscribe{(event : Event<String>) in
print(event) // 会接收到 a,b,c
}.addDisposeableTo(bag)
variable.value = 'b'
variable.value = 'c'
资源回收
- 当监听一个事件序列的时候,有消息事件来了,我们做某些事情。但是这个事件序列不再发出消息了,我们的监听也就没有什么存在价值了,所以我们需要释放我们这些监听资源,其实也就是每种编程语言中的内存资源释放
- 当我们对一个 subject 订阅的时候,订阅的内部会强引用这个subject,导致这个 subject 释放不掉。这是我们可以通过两种方式将 subject 释放掉, 通过调用 dispose() 或addDisposeableTo(bag)函数将其释放掉
- dispose 相当于 MRC 中手动调用 release 操作, 当调用完 dispose 后,因为观察者已经销毁,所以后面发送的所有事件都不会收到
let variable = Variable("a")
variable.asObserver().subscribe{(event : Event<String>) in
print(event) // 会接收到 a,
}.dispose()
variable.value = 'b'
variable.value = 'c'
- Dispose Bags: 除了上面的手动释放方法,还有这种自动释放的方式,类似 ARC, 通过调用
addDisposeableTo(bag)
方法,将我们的观察者添加到 bag 中,当 bag 销毁的时候,会将 bag 中的所有观察者销毁,类似自动释放池
UIBindingObserver
- UIBindingObserver 可以帮助我们创建自己的监听者,有时候RxCocoa(RxSwift中对UIKit的一个扩展库)给的扩展不够使用。这时我们就可以使用UIBindingObserver自己扩展。比如UITextField有个isEnable属性,我想把这个isEnable变成一个observer,就可以这样做:
extension Reactive where Base: UITextField{
var inputEnable: UIBindingObserver<Base, Result>{
return UIBindingObserver(UIElement: base) { textField, result in
textField.isEnabled = result.isValid
}
}
}
网友评论