RXSwift

作者: howhyone | 来源:发表于2021-10-19 21:44 被阅读0次

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

    import RxSwift
    import RxCocoa    
    var bag: DisposeBag = DisposeBag()
    
    
    1、监听按钮点击
            btn1.rx.tap.subscribe { (event: Event<Void>) 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<String>.never()
            never0.subscribe { (event: Event<String>) in
                print("------- \(event)")
            }.disposed(by: bag)
            //2、创建一个empty的observable
            let empty0 = Observable<String>.empty()
            empty0.subscribe { (event: Event<String>) in
                print("----event--- \(event)")
            }.disposed(by: bag)
            //3、创建一个just的observable
            let just = Observable<String>.just("10")
            just.subscribe { (event: Event<String>) 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<String>) in
                print("----of--- \(event)")
            }.disposed(by: bag)
            //5、创建一个from的observable
            let from = Observable.from([1,4,5])
            from.subscribe { (event: Event<Int>) in
                print("----from--- \(event)")
            }.disposed(by: bag)
            //6、创建一个create的observable:自定义的被观察者
            let create = createObservable(element: "model")
            create.subscribe { (event: Event<String>) in
                print("--create----- \(event)")
            }.disposed(by: bag)
            //7、创建一个Range的observable
            let range = Observable.range(start: 1, count: 10)
            range.subscribe { (event: Event<Int>) in
                print("---event---- \(event)")
            }.disposed(by: bag)
            //8、创建一个repeat
            let repeat0 = Observable.repeatElement("hello World")
            repeat0.take(4).subscribe { (event: Event<String>) in
                print("---repeat0---- \(event)")
            }.disposed(by: bag )
    // 自定义的被观察者
    func createObservable(element: String) -> Observable<String> {
            return Observable.create { (observer: AnyObserver<String>) -> 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<String>()
            publishSubject.onNext("1111")
            publishSubject.subscribe { (event: Event<String>) in
                print("------- \(event)")
            }.disposed(by: bag)
            publishSubject.onNext("aaa")
            // 打印结果: ------- next(aaa)
            //2、replaySubject:订阅者既能接受订阅后的事件也能接受订阅前的事件,接受的订阅前的事件个数取决于bufferSize(bufferSize小时,以临近订阅的事件倒数算)
            let replaySubject = ReplaySubject<String>.createUnbounded()
            replaySubject.onNext("aaaa")
            replaySubject.onNext("bbb")
            replaySubject.subscribe { (event: Event<String>) in
                print("---replaySubject---- \(event)")
            }.disposed(by: bag)
            replaySubject.onNext("ccc")
            // 3、behaviorSubject:订阅者既能接受订阅后的事件也能接受订阅前的最后一个事件,效果和replaySubject的bufferSize为1相同
            let behaviorSubject = BehaviorSubject<String>(value: "a") // "a":默认值
            behaviorSubject.onNext("a")
            behaviorSubject.onNext("b")
            behaviorSubject.subscribe { (event: Event<String>) in
                print("---behaviorSubject---- \(event)")
            }.disposed(by: bag)
            behaviorSubject.onNext("c")
            /* 打印结果:
             ---behaviorSubject---- next(b)
             ---behaviorSubject---- next(c)
             */
            //
    
    
           4、 let publishRelay = PublishRelay<String>()
            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<String>.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<String>.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<Double>
    }
    // 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<Int>) 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<Double> in
                return student.score
            }.subscribe { (event: Event<Double>) 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<Int> 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<String>.create { (observer: AnyObserver<String>) -> 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

          本文链接:https://www.haomeiwen.com/subject/sizaoltx.html