RxSwift 的那些事

2018-12-01  本文已影响21人  Lin__Chuan

观察者模式

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

观察者模式的使用

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


反馈回路

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

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

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

RxSwift 能做什么?

button.rx.tap
    .subscribe(onNext: {
        print("button Tapped")
    })
    .disposed(by: disposeBag)
scrollView.rx.contentOffset
            .subscribe(onNext: { contentOffset in
                print("contentOffset: \(contentOffset)")
            })
            .disposed(by: disposeBag)
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)
NotificationCenter.default.rx
        .notification(.UIApplicationWillEnterForeground)
        .subscribe(onNext: { (notification) in
            print("Application Will Enter Foreground")
        })
        .disposed(by: disposeBag)
user.rx.observe(String.self, #keyPath(User.name))
        .subscribe(onNext: { newValue in
            print("do something with newValue")
        })
        .disposed(by: disposeBag)
/// 用 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)
/// 用 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<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

上一篇下一篇

猜你喜欢

热点阅读