RxSwift
RxSwift核心概念
- 我们通过一张图来理解RxSwift,它主要有几个关键的概念Observable(可被观察的对象),Operators(操作符),Observer(观察者)
RxSwift把任何事物都看作是可观察的序列(使用泛型),比如一个数组,一个变量,-个函数,一个网络请求等。这样我们就可以把任何事物放到可被观察序列中去,然后经过operators转换成我们想要的数据,通过和观察者进行绑定,观察者就能观测到可被观察者序列中的数据流变化。
RxSwift简单的几个例子
- 通过create创建一个可观察序列
Observable<String>.create(_ subscribe: @escaping (AnyObserver<String>) -> Disposable) -> Observable<String>
我们看到这里有三个对象Observable(可观察者序列),AnyObserver(观察者), Disposable(用来管理声明周期的),我们需要一个闭包,这个闭包的签名是(observer)=> Disposable.
_ = Observable<String>.create { (observer) -> Disposable in
observer.on(.next("4"))
observer.on(.next("5"))
observer.on(.completed)
return Disposables.create()
}
- 通过subscribe进行订阅
func subscribe(_ on: @escaping (Event<String>) -> Void) -> Disposable
Event是一个枚举类型,.next进行下一步,.error出错了,.completed完成了序列。这样我们就可以订阅刚才的可被观察者序列了。
_ = Observable<String>.create { (observer) -> Disposable in
observer.on(.next("4"))
observer.on(.next("5"))
observer.on(.completed)
return Disposables.create()
}.subscribe({ (event) in
print(event.element)
})
这样可被观察序列发出的数据,都能被我们接收到了。
RxSwift在iOS中的应用
- target action
传统的target action
self.button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
func butonTapped() {
print("button点击事件")
}
rxswift的taret action
self.button.rx.tap
.subscribe(onNext: {
print("监听button点击事件")
})
.disposed(by: disposeBag)
我们看到两段代码在结构上明显下面更容易读,和理解。
- 代理的使用
传统写法
class ViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.delegate = self
}
}
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("contentOffset: \(self.scrollView.contentOffset)")
}
}
RxSwift的写法
class ViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.rx.contentOffset
.subscribe(onNext: { contentOffset in
print("contentOffset: \(contentOffset)")
})
.disposed(by: disposeBag)
}
}
- 闭包回调
传统写法
URLSession.shared.dataTask(with: URLRequest(url: url)) {
(data, response, error) in
guard error == nil else {
print("Data Task Error: \(error!)")
return
}
guard let data = data else {
print("Data Task Error: unknown")
return
}
print("Data Task Success with count: \(data.count)")
}.resume()
RxSwift写法
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)
- 通知
传统写法
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)
}
RxSwift写法
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.rx
.notification(.UIApplicationWillEnterForeground)
.subscribe(onNext: { (notification) in
print("Application Will Enter Foreground")
})
.disposed(by: disposeBag)
}
- KVO
传统写法
private var observerContext = 0
override func viewDidLoad() {
super.viewDidLoad()
user.addObserver(self, forKeyPath: #keyPath(User.name), options: [.new, .initial], context: &observerContext)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &observerContext {
let newValue = change?[.newKey] as? String
print("do something with newValue")
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
deinit {
user.removeObserver(self, forKeyPath: #keyPath(User.name))
}
RxSwift写法
override func viewDidLoad() {
super.viewDidLoad()
user.rx.observe(String.self, #keyPath(User.name))
.subscribe(onNext: { newValue in
print("do something with newValue")
})
.disposed(by: disposeBag)
}