RxSwift 2.Observer

文章目录
  1. 1. 如何创建 Observer
    1. 1.1. Observable 的 subscribe 方法
    2. 1.2. AnyObserver-- 任意观察者
    3. 1.3. Binder–UI 观察者

Observer: 监听 Observable Sequence,接受它传来的 events

observer

如何创建 Observer

Observable 的 subscribe 方法

创建观察者最直接的⽅法就是在 Observable 的 subscribe ⽅法后⾯描述,事件发⽣时,需要如 何做出响应。

1
2
3
4
5
6
7
tap.subscribe(onNext: { [weak self] in
self?.showAlert()
}, onError: { error in
print("发⽣错误: \(error.localizedDescription)")
}, onCompleted: {
print("任务完成")
})

subscribe 方法内部会产生 AnonymousObserver 对象(RxSwift 库私有的)

1
2
3
4
5
6
7
public func subscribe(_ on: @escaping (Event<Element>) -> Void)
-> Disposable {
let observer = AnonymousObserver { e in
on(e)
}
return self.asObservable().subscribe(observer)
}

AnyObserver-- 任意观察者

类注释:

A type-erased ObserverType.
将操作转发到具有相同 Element 类型的任意基础观察者,隐藏基础观察者类型的细节。

AnyObserver 可以⽤来描叙任意⼀种观察者。
eg: 打印⽹络请求结果:

1
2
3
4
5
6
7
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
2
3
4
5
6
7
8
9
10
11
12
13
14
let observer: AnyObserver<Data> = AnyObserver { (event) in 
switch event {
case .next(let data):
print("Data Task Success with count: \(data.count)")
case .error(let error):
print("Data Task Error: \(error)")
default:
break
}
}

URLSession.shared.rx.data(request: URLRequest(url: url))
.subscribe(observer)
.disposed(by: disposeBag)

⽤户名提示语是否隐藏:

1
2
3
usernameValid 
.bind(to: usernameValidOutlet.rx.isHidden)
.disposed(by: disposeBag)

可以看作是:

1
2
3
4
5
6
7
8
9
10
11
12
let observer: AnyObserver<Bool> = AnyObserver { [weak self] (event) in
switch event {
case .next(let isHidden):
self?.usernameValidOutlet.isHidden = isHidden
default:
break
}
}

usernameValid
.bind(to: observer)
.disposed(by: disposeBag)

Binder–UI 观察者

类注释:

强制执行接口绑定规则的观察者:

  • 无法绑定错误(在调试版本中,错误的绑定会导致致命错误,在发布版本中的错误会被记录)
  • 确保在特定的调度程序上执行绑定

Binder 不会保留目标,并且在释放目标的情况下,元素也不会绑定。

默认情况下,它绑定主调度程序上的元素

  1. Binder 主要有以下特征:
  • 处理 next 事件
  • 不处理错误事件
  • 确保绑定都是在给定 Scheduler 上执⾏(默认 MainScheduler)

⼀旦产⽣错误事件,在调试环境下将执⾏ fatalError,在发布环境下将打印错误信息。

  1. 示例,对比上面的 AnyObserver示例

由于这个观察者是⼀个 UI 观察者,所以它在响应事件时,只会处理 next 事件 并且更新 UI 的操作需要在主线程上执⾏。 因此⼀个更好的⽅案就是使⽤ Binder:

1
2
3
4
5
6
7
let observer: Binder<Bool> = Binder(usernameValidOutlet) { (view, isHidden) in 
view.isHidden = isHidden
}

usernameValid
.bind(to: observer)
.disposed(by: disposeBag)
  1. RxCocoa 中的 rx 扩展对于 Binder 的使用:

你也可以⽤这种⽅式来创建⾃定义的 UI 观察者。

1
2
3
4
5
6
7
extension Reactive where Base: UIView {
public var isHidden: Binder<Bool> {
return Binder(self.base) { view, hidden in
view.isHidden = hidden
}
}
}
1
2
3
4
5
6
7
extension Reactive where Base: UILabel {
public var text: Binder<String?> {
return Binder(self.base) { label, text in
label.text = text
}
}
}

引用:

Observer - 观察者