RxSwift 学习(一)—— 初探

1,237 阅读4分钟

一、函数响应式编程(FRP)

响应式编程 简称 RP(Reactive Programming),它是一种面向数据流和变化传播的编程方式。这意味着可以在编程语言中很方便地表达静态或者动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。响应式编程函数式编程 相结合起来,就是 函数式响应编程 FRP(Functional Reactive Programming)

前面在学 RAC 的时候,已经理解了函数响应式编程思想,分别介绍了 函数式编程响应式编程 的特点,这里就不再赘述。详情可见《RAC(ReactiveCocoa) 初探》。下面要介绍的 RxSwift 就是利用的 FRP 思想。如果有 Swift 语法不熟悉的可以先补习一下 Swift 语法,我就恶补了一下 Swift闭包语法,并总结了一下,有需要的朋友也可以去看一下我的文章《Swift中的闭包》

二、RxSwift

1、简介

ReactiveX(简写:Rx)是一个可以帮助我们简化异步编程的框架。而 RxSwift 是 Rx 的 Swift 版本。除了 RxSwift,还有 RxJava、RxJS、Rx.Net 等,对应的OC 版本则是 RAC(ReactiveCocoa),这里是 RxSwiftgithub 地址 ,已经有了将近 17000 颗星了。

RxSwift 的特点:

  • 复合 - Rx 就是复合的代名词
  • 复用 - 因为它易复合
  • 清晰 - 因为声明都是不可变更的
  • 易用 - 因为它抽象的了异步编程,使我们统一了代码风格
  • 稳定 - 因为 Rx 是完全通过单元测试的

2、RxSwift 的导入

我采用的是 cocoaPods 的导入方式,在 Podfile 文件中写如

# Podfile
use_frameworks!
target 'YOUR_TARGET_NAME' do
    pod 'RxSwift', '~> 5.0'
    pod 'RxCocoa', '~> 5.0'
end

替换 YOUR_TARGET_NAME 然后在 Podfile 目录下, 终端输入:

$ pod install

在项目中用到的地方引入即可

import RxSwift
import RxCocoa

3、RxSwift 的常用方式

现在我们通过了解几个 RxSwift 的常用方式,来了解一下它的强大之处吧!

(1) 按钮点击事件

传统实现方法:

button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
func buttonTapped() {
    print("button Tapped")
}

Rx 实现:

button.rx.tap
    .subscribe(onNext: {
        print("button Tapped")
    })
    .disposed(by: disposeBag)
  • 你不需要使用 Target Action,这样使得代码逻辑清晰可见。

(2) 代理

这里我们以 UIScrollViewDelegate 的偏移量代理方法为例, 传统实现方法:

class ViewController: UIViewController {
    ...
    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self
    }
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("contentOffset: \(scrollView.contentOffset)")
    }
}

Rx 实现:

class ViewController: UIViewController {
    ...
    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView.rx.contentOffset
            .subscribe(onNext: { contentOffset in
                print("contentOffset: \(contentOffset)")
            })
            .disposed(by: disposeBag)
    }
}
  • 你不需要书写代理的配置代码,就能获得想要的结果。

(3) 通知

传统实现方法:

var ntfObserver: NSObjectProtocol!

override func viewDidLoad() {
    super.viewDidLoad()

    ntfObserver = NotificationCenter.default.addObserver(
          forName: .UIApplicationWillEnterForeground,
          object: nil, queue: nil) { (notification) in
        print("Application Will Enter Foreground")
    }
}

deinit {
    NotificationCenter.default.removeObserver(ntfObserver)
}

Rx 实现:

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.rx
        .notification(.UIApplicationWillEnterForeground)
        .subscribe(onNext: { (notification) in
            print("Application Will Enter Foreground")
        })
        .disposed(by: disposeBag)
}
  • 你不需要去管理观察者的生命周期,这样你就有更多精力去关注业务逻辑。

(4) timer 定时器

Rx 实现:

func setupTimer() {
    timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        timer.subscribe(onNext: { (num) in
            print(num)
    })
    .disposed(by: disposeBag)
}

(5) 手势

Rx 实现:

func setupGestureRecognizer(){
    let tap = UITapGestureRecognizer()
    self.label.addGestureRecognizer(tap)
    self.label.isUserInteractionEnabled = true
    tap.rx.event.subscribe(onNext: { (tap) in
        print(tap.view)
    })
    .disposed(by: disposeBag)
}

看了上面的的 Rx 实现方式,是不是觉得特别方便快捷。了解了用法,我们再来深入了解一下 RxSwift 的核心吧。

4、RxSwift 的核心

Observable 是一个可监听的 Sequence(序列)。分为有穷序列和无穷序列,主要就是用来形成一条数据流。它有三种事件:next、completederror

  • next 事件主要是当 Observable 里出现新的数据时会发出的事件,同时该事件会携带新的数据对象。
  • completed 事件是当 Observable 不再有新的数据出现,Observable被标记完成,并且将数据流终结。
  • error 事件是指当数据流遇到了错误会发出的事件,该事件也会导致 Observable 被终结。

下面是一个代码实现的整个流程:

// 1:创建序列
// AnonymousObservable -> producer.subscriber -> run
let ob = Observable<Any>.create { (obserber) -> Disposable in
    // 3:发送信号
    obserber.onNext("发送信号")
    obserber.onCompleted()
    return Disposables.create()
}
// 2:订阅信号
let _ = ob.subscribe(onNext: { (text) in
    print("订阅到:\(text)")
}, onError: { (error) in
    print("错误: \(error)")
}, onCompleted: {
    print("完成")
}) {
    print("销毁")
}

到此我们只是先对 RxSwift 进行了一次简单的初探,了解了它的强大之处和简单的用法,以及它的核心原理。后面我还会更深一步去学习使用 RxSwift

以上的总结参考了并部分摘抄了以下文章,非常感谢以下作者的分享!:

1、《RxSwift 中文文档》

2、作者Philm_iOS的《函数响应式编程》

3、作者我只不过是出来写写代码的《RAC(ReactiveCocoa)介绍(一)——基本介绍》

4、turtleeeee的《RxSwift的学习之路(一)——Observable》

转载请备注原文出处,不得用于商业传播——凡几多