声明: 部分资料摘自 http://www.jianshu.com/p/431f645cb805 和 http://www.codertian.com/2016/12/01/RxSwift-ru-keng-ji-learn-the-difficulty
ObserverType: Supports push-style iteration over an observable sequence. ObserverType是观察者Observer需要遵从的协议
/// Supports push-style iteration over an observable sequence.
public protocol ObserverType {
/// The type of elements in sequence that observer can observe.
associatedtype E
/// Notify observer about sequence event.
///
/// - parameter event: Event that occured.
func on(_ event: Event<E>)
}
ObservableType: Represents a push style sequence。ObservableType是Observable需要遵从的协议。
/// Represents a push style sequence.
public protocol ObservableType : ObservableConvertibleType {
/// Type of elements in sequence.
associatedtype E
func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E
...
}
Observable是一种像信号一样的序列,而信号就需要有人监听这些信号。ObservableType协议中定义的subscribe函数就是一种简便的订阅信号的一种方法。这里的subscribe函数就是把消息发给观察者。
extension ObservableType {
/**
Creates new subscription and sends elements to observer.
In this form it's equivalent to `subscribe` method, but it communicates intent better, and enables
writing more consistent binding code.
- parameter observer: Observer that receives events.
- returns: Disposable object that can be used to unsubscribe the observer.
*/
public func bindTo<O: ObserverType where O.E == E>(_ observer: O) -> Disposable
/**
Creates new subscription and sends elements to variable.
In case error occurs in debug mode, `fatalError` will be raised.
In case error occurs in release mode, `error` will be logged.
- parameter variable: Target variable for sequence elements.
- returns: Disposable object that can be used to unsubscribe the observer.
*/
public func bindTo(_ variable: RxSwift.Variable<Self.E>) -> Disposable
...
bindTo是ObservableType协议的扩展方法,bindTo等同于subscribe,但依RxCocoa中所说的,bindTo的内在实现更好,并且bindTo这个名称也很直观,所以当引入了RxCocoa这个framework后一般我都是用bindTo来实现UI的订阅。
- bindTo其中一个用的比较多的重载方法
bindTo<O: ObserverType where O.E == E>(_ observer: O) -> Disposable
,这个方法有一个参数,从方法泛型的声明中可以得知,参数的类型为一个观察者类型,且这个观察者能够接受到的事件流元素的类型要跟被观察者的一样(O.E == E)。这个方法意图就是将一个被观察者与一个指定的观察者进行绑定,被观察者事件流中发出的所有事件元素都会让观察者接收。
在MVVM架构模式中,此方法主要用于视图(View)层跟视图模型(ViewModel)层或视图层跟视图层的绑定,例如:
<pre>
textField.rx.text
.bindTo(label.rx.text)
.disposed(by: disposeBag)
</pre>
- UITextField的
rx.text
的属性类型是ControlProperty
,不仅是观察者类型,还是被观察者类型:
struct ControlProperty<PropertyType> : ControlPropertyType
...
protocol ControlPropertyType: ObservableType, ObserverType
> * UILabel中的`rx.text`的属性类型是**`UIBindingObserver`**, 只是单纯的观察者类型。
>
```swift
class UIBindingObserver<UIElementType, Value> : ObserverType where UIElementType: AnyObject {
public typealias E = Value
weak var UIElement: UIElementType?
>
/// Initializes `ViewBindingObserver` using
public init(UIElement: UIElementType, binding: @escaping (UIElementType, Value) -> Void)
...
}
- UIBindingObserver是一个类,他的初始化方法中,有两个参数,第一个参数是要被绑定的视图的实例,第二个参数是一个闭包,闭包参数是被绑定了的视图本身,和一个由绑定的被观察者中所发射出来的事件元素。
在RxCocoa框架中,UILable中的text
属性是这样实现的:
public struct Reactive<Base> {
/// Base object to extend.
public let base: Base
...
}
>
extension Reactive where Base: UILabel {
>
/// Bindable sink for `text` property.
public var text: UIBindingObserver<Base, String?> {
return UIBindingObserver(UIElement: self.base) { label, text in
label.text = text
}
}
...
- UIBindingObserver这个东西很有用的,可以用来创建我们自己的监听者。因为有时候RxCocoa给的扩展不够我们使用,比如一个UITextField有个isEnabled属性,我想把这个isEnabled变为一个observer,我们可以这样做:
extension Reactive where Base: UITextField {
var inputEnabled: UIBindingObserver<Base, Bool> {
return UIBindingObserver(UIElement: self.base) { textField, enabled in
textField.isEnabled = enabled
}
}
}
// 当textField1输入的字符长度大于3时, textField2的输入框变成激活的。
textField1.rx.text
.orEmpty //Transforms ControlProperty of type `String?` into ControlProperty of type `String`.
.map{ $0.characters.count > 3 }
.bindTo(textField2.rx.inputEnabled)
.disposed(by: disposeBag)
- bindTo的另外一个用得比较多的重载方法是:
bindTo(_ variable: RxSwift.Variable<Self.E>) -> Disposable
,这个方法将一个被观察者与一个Variable(变量)绑定在一起,这个变量的元素类型跟被观察者的事件元素类型一致。此方法作用就是把从被观察者事件流中发射出的事件元素存入变量中。