美文网首页
RxSwift 的那些事

RxSwift 的那些事

作者: Lin__Chuan | 来源:发表于2018-12-01 00:52 被阅读21次

    观察者模式

    被观察者给观察者(订阅者)发送消息(通知), 观察者接收消息, 做相应的处理.
    比如妈妈照顾宝宝, 妈妈是观察者, 宝宝是被观察者.
    只要被观察者发出了某些事件比如宝宝哭声, 通知到订阅者, 订阅者就会相应处理.

    观察者模式的使用

    在 App 架构中, View 层的展示依赖于 Model层数据的更新.


    反馈回路

    在观察者模式中有几种常用到的技术

    • Notification
      Notification 将值从单一源广播给若干个收听者.
    • KVO
      键值监听可以将某个对象上属性的改变报告给另一个对象
    • 响应式编程
      响应式编程也是一种用来交流变更的工具, 不过和通知或者 KVO 不同的是, 它专注于在源和目标之间的变更, 让逻辑可以在部件之间传输信息的同时得以表达. 这是一种单向绑定.

    macOS 上的 Cocoa 包含 Cocoa 绑定技术, 它是一种双向绑定. 在一个方向上建立连接, 在反方向上也建立连接.

    在上一篇文章中介绍了KVO的本质, 今天这里主要涉及的是响应式编程中, ReactiveX 的 Swift 实现 RxSwift.

    RxSwift 能做什么?

    • 1. Target Action
      用 Rx 实现 button 点击
    button.rx.tap
        .subscribe(onNext: {
            print("button Tapped")
        })
        .disposed(by: disposeBag)
    
    • 2. 代理
      用 Rx 实现滚动事件代理
    scrollView.rx.contentOffset
                .subscribe(onNext: { contentOffset in
                    print("contentOffset: \(contentOffset)")
                })
                .disposed(by: disposeBag)
    
    • 3. 闭包回调
    URLSession.shared.rx.data(request: URLRequest(url: url))
        .subscribe(onNext: { data in
            print("Data Task Success with count: \(data.count)")
        }, onError: { error in
            print("Data Task Error: \(error)")
        })
        .disposed(by: disposeBag)
    
      1. 通知
    NotificationCenter.default.rx
            .notification(.UIApplicationWillEnterForeground)
            .subscribe(onNext: { (notification) in
                print("Application Will Enter Foreground")
            })
            .disposed(by: disposeBag)
    
    • 5. KVO
    user.rx.observe(String.self, #keyPath(User.name))
            .subscribe(onNext: { newValue in
                print("do something with newValue")
            })
            .disposed(by: disposeBag)
    
    • 6. 处理多个任务之间依赖关系
      例如, 先通过用户名密码取得 Token 然后通过 Token 取得用户信息.
    /// 用 Rx 封装接口
    enum Api {
    
        /// 通过用户名密码取得一个 token
        static func token(username: String, password: String) -> Observable<String> { ... }
    
        /// 通过 token 取得用户信息
        static func userInfo(token: String) -> Observable<UserInfo> { ... }
    }
    
    /// 通过用户名和密码获取用户信息
    Api.token(username: "beeth0ven", password: "987654321")
        .flatMapLatest(Api.userInfo)
        .subscribe(onNext: { userInfo in
            print("获取用户信息成功: \(userInfo)")
        }, onError: { error in
            print("获取用户信息失败: \(error)")
        })
        .disposed(by: disposeBag)
    
    • 7. 等待多个并发任务完成后处理结果
      例如, 需要将两个网络请求合并成一个.
    /// 用 Rx 封装接口
    enum Api {
    
        /// 取得老师的详细信息
        static func teacher(teacherId: Int) -> Observable<Teacher> { ... }
    
        /// 取得老师的评论
        static func teacherComments(teacherId: Int) -> Observable<[Comment]> { ... }
    }
    
    /// 同时取得老师信息和老师评论
    Observable.zip(
          Api.teacher(teacherId: teacherId),
          Api.teacherComments(teacherId: teacherId)
        ).subscribe(onNext: { (teacher, comments) in
            print("获取老师信息成功: \(teacher)")
            print("获取老师评论成功: \(comments.count) 条")
        }, onError: { error in
            print("获取老师信息或评论失败: \(error)")
        })
        .disposed(by: disposeBag)
    

    更多的使用可以查看官方Demo.

    从上面的例子可以看到, RxSwift 的使用可以简化代码, 不过我个人建议不要滥用, 因为对于不用 RxSwift 的人来说, 代码可读性较差了.

    RxSwift 中有非常多的操作符, 用于应对各种不同的情况, 详情可以查看 RxSwift 中的操作符

    作为一个响应式编程的基础框架, RxSwift 除了可以在常规 MVC 架构的程序中使用外, 它最大的用武之地在于 MVVM, RxFeedback, Reactkit.

    RxSwift 核心

    • Observable: 可被监听的序列, 用来产生事件.
      所有的事物都是序列, Observable 可以用于描述元素异步产生的序列.
    • Observer - 观察者, 用来响应事件.
      响应事件的都是观察者(订阅者), 对事件做出不同的处理.
    • Operator - 创建变化组合事件
      观察者通过 Operator 对事件做出不同的处理.
    • Disposable - 管理绑定(订阅)的生命周期
      • 一般一个序列如果发出了 error 或者 completed 事件, 那么所有内部资源都会被释放.
      • 可以对返回的可被清除的资源(Disposable) 调用 dispose 方法, 提前释放这些资源或取消订阅.
    • Schedulers - 线程队列调配
      用于控制任务在哪个线程或队列运行.
    // 创建被观察者
    // Observable<String>
    let text = usernameOutlet.rx.text.orEmpty.asObservable()
    
    // Observable<Bool>
    let passwordValid = text
        // Operator 创建一个新的事件, 密码长度大于minimalUsernameLength
        .map { $0.characters.count >= minimalUsernameLength }
    
    // Observer<Bool>
    let observer = passwordValidOutlet.rx.isHidden
    
    // Disposable
    let disposable = passwordValid
        // Scheduler 用于控制任务在那个线程队列运行
        .subscribeOn(MainScheduler.instance)
        .observeOn(MainScheduler.instance)
        .bind(to: observer)
    ...
    
    // 取消绑定,你可以在退出页面时取消绑定
    disposable.dispose()
    

    RxSwift 的源码解读

    这才是本片最大的重点.

    参考自
    RxSwift中文文档
    RxSwift 官方github

    相关文章

      网友评论

          本文标题:RxSwift 的那些事

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