Rx 简介
一、什么是 Rx?
Rx 是 Reactive X 的缩写,简单来说就是基于异步 Event(事件)序列的响应式编程。Rx 可以简化异步编程方法,并提供更优雅的数据绑定,让我们可以时刻响应新的数据同时顺序地处理它们。ReactiveX(Reactive Extensions)是通过可观察的流实现异步编程的一种API,它结合了观察者模式、迭代器模式和函数式编程的精华。RxSwift 是 ReactiveX 编程思想的一种实现,几乎每一种语言都会有那么一个 Rx[xxxx] 框架,比如Rxswift,RxJava,RxJS 等。
二、Rx 库
Rx 本身可以说是一种跨平台的标准,它有自己的社区论坛,不管是web 还是移动开发,都能用 Rx 的思维和方法来完成你的工作。作为一种跨平台标准,目前已经有许多基于不同开发语言的 Rx 的库。除了 RxSwift 之外,还有 RxJava,RxJS, RxKotlin, Rx.NET等库。Rx 库虽然用的语言不同,但它们之间其实都是相通的,都有相同的 API。所以说如果以后使用别的语言做其他的方面的开发,同样是可以使用相同的思维甚至相同的方法接口(除了语言不同)来编程。ReactiveX 不仅是一个编程接口,它是一种编程思想的突破,它影响了许多其它的程序库和框架以及编程语言。它拓展了观察者模式,能够自由组合多个异步事件,而不需要去关心线程,同步,线程安全,并发数据以及I/O阻塞。RxSwift 是 Rx 为 Swift 语言开发的一门函数响应式编程语言, 它可以代替iOS系统的 Target Action / 代理 / 闭包 / 通知 / KVO,同时还提供网络、数据绑定、UI事件处理、UI的展示和更新、多线程等。
RxSwift 的安装与配置
一、手动安装
从 Github 上下载最新的代码;将下载下来的源码包中 Rx.xcodeproj 拖拽至工程中;工程 -> General -> Embedded Binaries 项,把 iOS 版的 RxSwift.framework、RxCocoa.framework 添加进来。
二、CocoaPods 安装
替换 YOUR_TARGET_NAME 然后在 Podfile 目录下;
use_frameworks
!
target
'RxSwift基本使用' do
# Comment the next line if you don't want to use dynamic frameworks
# Pods for RxSwift基本使用
pod
'RxSwift', '~> 5'
pod
'RxCocoa', '~> 5'
target
'RxSwift基本使用Tests' do
inherit
! :search_paths
# Pods for testing
pod
'RxBlocking', '~> 5'
pod
'RxTest', '~> 5'
end
target
'RxSwift基本使用UITests' do
# Pods for testing
end
end
终端输入
$ pod install
使用 RxSwift 的地方 import
import RxSwift
import RxCocoa
RxSwift:它只是基于 Swift 语言的 Rx 标准实现接口库,所以 RxSwift 里不包含任何 Cocoa 或者 UI方面的类。 RxCocoa:是基于 RxSwift针对于 iOS开发的一个库,它通过 Extension 的方法给原生的比如 UI 控件添加了 Rx 的特性,使得容易订阅和响应这些控件的事件。
使用示例
一、UITextField
监听单个 textField 内容的变化(文本响应):
self.textField
.rx
.text
.orEmpty
.subscribe(onNext
: { (text
) in
if text
.count
> 0 {
print(text
)
}
})
.disposed(by
: disposeBag
)
效果展示
1
12
123
1234
12345
123456
1234567
12345678
123456789
使用 change 事件效果一样:
self.textField
.rx
.text
.orEmpty
.changed
.subscribe(onNext
: {
if text
.count
> 0 {
print(text
)
}
})
.disposed(by
: disposeBag
)
二、UIButton
实现UIButton点击事件响应:
self.button
.rx
.tap
.subscribe(onNext
: { [weak
self] in
print(self?.button
.titleLabel
?.text as Any
)
}).disposed(by
: disposeBag
)
修改UIButton的Control.Events:
self.button
.rx
.controlEvent(.touchUpOutside
)
将UITextField的输入内容绑定到UIButton属性:
self.textField
.rx
.text
.bind(to
: self.button
.rx
.title())
.disposed(by
: disposeBag
)
效果展示
三、UIScrollView
self.scrollView
.rx
.contentOffset
.subscribe(onNext
: { (content
) in
self.view
.backgroundColor
= UIColor
.init(red
: content
.y
/ 255.0 * 0.4, green
: content
.y
/ 255.0 * 0.6, blue
: content
.y
/ 255.0 * 0.8, alpha
: 1)
})
.disposed(by
: disposeBag
)
四、手势
let gesture
= UITapGestureRecognizer()
self.label
.isUserInteractionEnabled
= true
self.label
.addGestureRecognizer(gesture
)
gesture
.rx
.event
.subscribe(onNext
: { (tap
) in
print(tap
.view as Any
)
})
.disposed(by
: disposeBag
)
五、通知
NotificationCenter
.default.rx
.notification(UIResponder
.keyboardDidShowNotification
)
.subscribe(onNext
: { (notification
) in
print(notification
)
})
.disposed(by
: disposeBag
)
六、KVO
self.boy
.rx
.observeWeakly(String
.self, "name")
.subscribe(onNext
: { (value
) in
print(value as Any
)
})
.disposed(by
: disposeBag
)
override func
touchesBegan(_ touches
: Set
<UITouch
>, with event
: UIEvent
?) {
self.boy
.name
= "girl"
print(self.boy
.name
)
}
七、NSTimer
避免了实现定时器的runloop影响、销毁问题、线程问题;
let timer
= Observable
<Int
>.timer(1, period
: 2, scheduler
: MainScheduler
.instance
)
timer
.subscribe
{ (event
) in
print(event
)
}.disposed(by
: disposeBag
)
func
setupTimer() {
timer
= Observable
<Int
>.interval(1, scheduler
: MainScheduler
.instance
)
timer
.subscribe(onNext
: { (num
) in
print("\(num)")
}).disposed(by
: disposeBag
)
}
八、URLSession 网络请求
URLSession
.shared
.rx
.response(request
: URLRequest
.init(url
: URL
.init(string
: "https://www.baidu.com")!))
.subscribe(onNext
: { (response
, data
) in
print(response
)
})
.disposed(by
: disposeBag
)
九、UITextView
UITextView有如下委托回调方法:
didBeginEditing:开始编辑didEndEditing:结束编辑didChange:编辑内容发生改变didChangeSelection:选中部分发生变化
textView
.rx
.didBeginEditing
.subscribe(onNext
: {
print("开始编辑")
})
.disposed(by
: disposeBag
)
textView
.rx
.didEndEditing
.subscribe(onNext
: {
print("结束编辑")
})
.disposed(by
: disposeBag
)
textView
.rx
.didChange
.subscribe(onNext
: {
print("内容发生改变")
})
.disposed(by
: disposeBag
)
textView
.rx
.didChangeSelection
.subscribe(onNext
: {
print("选中部分发生变化")
})
.disposed(by
: disposeBag
)
完整示例
RxSwift基本使用