RXSwift

一、介绍
swift响应式编程,监听被观察者的事件、当触发时间时、发送给订阅者
二、UIButton、UITextField、UILabel、UIScrollView的应用

import RxSwift
import RxCocoa    
var bag: DisposeBag = DisposeBag()


1、监听按钮点击
        btn1.rx.tap.subscribe { (event: Event) in
            print("btn1 点击")
        }.disposed(by: bag)
2、UITextField文字改变
    public func subscribe(onNext: ((Self.Element) -> Void)? = nil, onError: ((Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil) -> RxSwift.Disposable

        textField1.rx.text.subscribe {[weak self] (text: String?) in
            print("------- \(String(describing: text))")
        }.disposed(by: bag)
3、绑定两个被观察者、textField的文字显示在label
        textField1.rx.text.bind(to: label1.rx.text).disposed(by: bag)
4、KVO观察属性
        label1.rx.observe(CGRect.self, "frame").subscribe { (frame: CGRect?) in
            print("------- \(frame ?? CGRect.zero)")
        }.disposed(by: bag)
5、UIScrollView的滚动
        scrollView.rx.contentOffset.subscribe { (offset: CGPoint) in
            print("------- \(offset)")
        }.disposed(by: bag)

三、创建常见的observable

//1、创建一个never的Obserable
        let never0 = Observable.never()
        never0.subscribe { (event: Event) in
            print("------- \(event)")
        }.disposed(by: bag)
        //2、创建一个empty的observable
        let empty0 = Observable.empty()
        empty0.subscribe { (event: Event) in
            print("----event--- \(event)")
        }.disposed(by: bag)
        //3、创建一个just的observable
        let just = Observable.just("10")
        just.subscribe { (event: Event) in
            print("---just---- \(event)")
        }.disposed(by: bag)
        just.subscribe { (str: String) in
            print("---str---- \(str)")
        }.disposed(by: bag)
        //4、创建一个of的observable
        let of = Observable.of("a","b","c")
        of.subscribe { (event: Event) in
            print("----of--- \(event)")
        }.disposed(by: bag)
        //5、创建一个from的observable
        let from = Observable.from([1,4,5])
        from.subscribe { (event: Event) in
            print("----from--- \(event)")
        }.disposed(by: bag)
        //6、创建一个create的observable:自定义的被观察者
        let create = createObservable(element: "model")
        create.subscribe { (event: Event) in
            print("--create----- \(event)")
        }.disposed(by: bag)
        //7、创建一个Range的observable
        let range = Observable.range(start: 1, count: 10)
        range.subscribe { (event: Event) in
            print("---event---- \(event)")
        }.disposed(by: bag)
        //8、创建一个repeat
        let repeat0 = Observable.repeatElement("hello World")
        repeat0.take(4).subscribe { (event: Event) in
            print("---repeat0---- \(event)")
        }.disposed(by: bag )
// 自定义的被观察者
func createObservable(element: String) -> Observable {
        return Observable.create { (observer: AnyObserver) -> Disposable in
            observer.onNext(element)
            observer.onCompleted()
            return Disposables.create()
        }
    }

四:Subject:既是一个观察者,也可为一个被观察者,既能被订阅也能发送事件
RxRelay和 Subjects 相似,唯一的区别是不会接受 onError 或 onCompleted 这样的终止事件,可通过value取当前的值
在将非 Rx 样式的 API 转化为 Rx 样式时,Subjects 是非常好用的。不过一旦 Subjects 接收到了终止事件 onError 或 onCompleted。他就无法继续工作了,也不会转发后续任何事件。有些时候这是合理的,但在多数场景中这并不符合我们的预期。
在这些场景中一个更严谨的做法就是,创造一种特殊的 Subjects,这种 Subjects 不会接受终止事件。有了他,我们将 API 转化为 Rx 样式时,就不必担心一个意外的终止事件,导致后续事件转发失效。

        //1、PublishSubject 订阅者只能接受订阅后发出的事件
        let publishSubject = PublishSubject()
        publishSubject.onNext("1111")
        publishSubject.subscribe { (event: Event) in
            print("------- \(event)")
        }.disposed(by: bag)
        publishSubject.onNext("aaa")
        // 打印结果: ------- next(aaa)
        //2、replaySubject:订阅者既能接受订阅后的事件也能接受订阅前的事件,接受的订阅前的事件个数取决于bufferSize(bufferSize小时,以临近订阅的事件倒数算)
        let replaySubject = ReplaySubject.createUnbounded()
        replaySubject.onNext("aaaa")
        replaySubject.onNext("bbb")
        replaySubject.subscribe { (event: Event) in
            print("---replaySubject---- \(event)")
        }.disposed(by: bag)
        replaySubject.onNext("ccc")
        // 3、behaviorSubject:订阅者既能接受订阅后的事件也能接受订阅前的最后一个事件,效果和replaySubject的bufferSize为1相同
        let behaviorSubject = BehaviorSubject(value: "a") // "a":默认值
        behaviorSubject.onNext("a")
        behaviorSubject.onNext("b")
        behaviorSubject.subscribe { (event: Event) in
            print("---behaviorSubject---- \(event)")
        }.disposed(by: bag)
        behaviorSubject.onNext("c")
        /* 打印结果:
         ---behaviorSubject---- next(b)
         ---behaviorSubject---- next(c)
         */
        //


       4、 let publishRelay = PublishRelay()
        publishRelay.subscribe { (str: String) in
            print("---publishRelay---- \(str)")
        }.disposed(by: bag)
        publishRelay.accept("111")
        /**打印:
            ---publishRelay---- 111
          **/
      // behaviorRelay : 代替variable,和behaviorSubject类似,没onComplete和onError事件,可以通过value获取值
      5、  let behavior = BehaviorRelay.init(value: "")
        behavior.subscribe { (str: String) in
            print("---behavior---- \(str)")
        }.disposed(by: bag)
        behavior.accept("2222")
        print("----behavior.value--- \(behavior.value)")
        behavior.accept("3333")
          /**打印结果:
                ---behavior---- 
                ---behavior---- 2222
              ----behavior.value--- 2222
            ---behavior---- 3333
      */
       6、 let replayRelay = ReplayRelay.create(bufferSize: 2)
        replayRelay.accept("44444")
        replayRelay.accept("5555")
        replayRelay.accept("6666")
        replayRelay.subscribe { (str: String) in
            print("---replayRelay---- \(str)")
        }.disposed(by: bag)
        replayRelay.accept("7777")
        /* 打印结果:
            ---replayRelay---- 5555
          ---replayRelay---- 6666
          ---replayRelay---- 7777
      */

五:映射变换

struct Student {
    var score: BehaviorSubject
}
// swift中的map
        let arr = ["d","b"]
        let arr1 = arr.map { (str: String) -> String in
            return str.appending("hh")
        }
        print("----\(arr1)--- \(arr)")
        //1、RxSwift的map、用于变换基本数据类型
        Observable.of(1,2,3,4).map { (num: Int) -> Int in
            return num * num
        }.subscribe { (event: Event) in
            print("---map---- \(event)")
        }.disposed(by: bag)
        //2、flatMapLatest 订阅最新的被观察者、用于变换自定义类型
        let student1 = Student(score: BehaviorSubject(value: 100))
        let student2 = Student(score: BehaviorSubject(value: 0))
        
        let behaviorSubject = BehaviorSubject(value: student1)
        behaviorSubject.flatMapLatest { (student: Student) -> BehaviorSubject in
            return student.score
        }.subscribe { (event: Event) in
            print("---flatMapLatest---- \(event)")
        }.disposed(by: bag)
       
        student1.score.onNext(60)
        student2.score.onNext(30)

六:资源释放:当订阅的对象不再发送事件了,需要释放被订阅的对象

1、.disposed(by: bag) :释放时期和bag相同
2、.dispose() :立即释放订阅的对象,后边发送事件不再接受

七:catch:捕获到error返回一个同类型的observable
retry: 接受到错误后,重试

        let behaviorSub1 = BehaviorSubject(value: 0)
        let behaviorSub2 = BehaviorSubject.of(1,3)
        behaviorSub1.catch({ (error) -> Observable in
            print("------- \(error)")
            return behaviorSub2.asObservable()
        }).subscribe { (num: Int) in
            print("---behaviorSub1---- \(num)")
        }.disposed(by: bag)
        behaviorSub1.onError(ObError.error1)
/* 打印结果
---behaviorSub1---- 0
------- error1
---behaviorSub1---- 1
---behaviorSub1---- 3
*/
      var isFail = true
        let retryObservable = Observable.create { (observer: AnyObserver) -> Disposable in
            observer.onNext("成功1")
            if isFail {
                observer.onError(ObError.error1)
                isFail = false
            }
            observer.onNext("retry success")
            observer.onCompleted()
            return Disposables.create()
        }
        retryObservable.retry(2).subscribe { (str: String) in
            print("------- \(str)")
        }.disposed(by: bag)
/*打印结果
------- 成功1
------- 成功1
------- retry success
*/

八:combineLatest:将多个信号的值合并为一个值,任一的信号有值改变,combineLatest就执行一次
zip:成对新的信号出现才执行一次,1和2一次;3和4一次
map:修改每个元素的值
filter:过滤元素,获取符合条件的结果

        Observable.combineLatest(<#T##source1: ObservableType##ObservableType#>, <#T##source2: ObservableType##ObservableType#>, resultSelector: <#T##(ObservableType.Element, ObservableType.Element) throws -> _#>)

        Observable.combineLatest(subject1, subject2).skip(1).subscribe { (str1, str2) in
            print("------- \(str1 ?? "$$")\(str2 ?? "^^")")
        }.disposed(by: bag)

        Observable.zip(subject1, subject2).skip(1).subscribe { (str1, str2) in
            print("======== \(str1 ?? "$$")\(str2 ?? "^^")")
        }.disposed(by: bag)

        subject1.skip(1).map { str2 in
            return (str2 ?? "NULL") + "dddd"
        }.filter({ (str1: String) in
            return str1.contains("123")
        }).subscribe { (str1: String) in
            print("++++++ \(str1)")
        }.disposed(by: bag)

        subject1.onNext("123")
        subject2.accept("567")
        subject1.onNext("890")
        subject2.accept("09090") // 不添加则只自行一次,890不触发通知
打印:
------- 123^^
------- 123567
------- 890567
------- 89009090

======== 123567
======== 89009090

++++++ 123dddd

你可能感兴趣的:(RXSwift)