聲明: 部分資料摘自 http://www.reibang.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需要遵從的協(xié)議
/// 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需要遵從的協(xié)議。
/// 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是一種像信號(hào)一樣的序列簇爆,而信號(hào)就需要有人監(jiān)聽(tīng)這些信號(hào)。ObservableType協(xié)議中定義的subscribe函數(shù)就是一種簡(jiǎn)便的訂閱信號(hào)的一種方法峦嗤。這里的subscribe函數(shù)就是把消息發(fā)給觀察者。
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協(xié)議的擴(kuò)展方法屋摔,bindTo等同于subscribe烁设,但依RxCocoa中所說(shuō)的,bindTo的內(nèi)在實(shí)現(xiàn)更好钓试,并且bindTo這個(gè)名稱(chēng)也很直觀装黑,所以當(dāng)引入了RxCocoa這個(gè)framework后一般我都是用bindTo來(lái)實(shí)現(xiàn)UI的訂閱副瀑。
- bindTo其中一個(gè)用的比較多的重載方法
bindTo<O: ObserverType where O.E == E>(_ observer: O) -> Disposable
,這個(gè)方法有一個(gè)參數(shù)恋谭,從方法泛型的聲明中可以得知糠睡,參數(shù)的類(lèi)型為一個(gè)觀察者類(lèi)型,且這個(gè)觀察者能夠接受到的事件流元素的類(lèi)型要跟被觀察者的一樣(O.E == E)疚颊。這個(gè)方法意圖就是將一個(gè)被觀察者與一個(gè)指定的觀察者進(jìn)行綁定狈孔,被觀察者事件流中發(fā)出的所有事件元素都會(huì)讓觀察者接收。
在MVVM架構(gòu)模式中材义,此方法主要用于視圖(View)層跟視圖模型(ViewModel)層或視圖層跟視圖層的綁定均抽,例如:
<pre>
textField.rx.text
.bindTo(label.rx.text)
.disposed(by: disposeBag)
</pre>
- UITextField的
rx.text
的屬性類(lèi)型是ControlProperty
,不僅是觀察者類(lèi)型母截,還是被觀察者類(lèi)型:
struct ControlProperty<PropertyType> : ControlPropertyType
...
protocol ControlPropertyType: ObservableType, ObserverType
> * UILabel中的`rx.text`的屬性類(lèi)型是**`UIBindingObserver`**, 只是單純的觀察者類(lèi)型到忽。
>
```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是一個(gè)類(lèi)橄教,他的初始化方法中清寇,有兩個(gè)參數(shù),第一個(gè)參數(shù)是要被綁定的視圖的實(shí)例护蝶,第二個(gè)參數(shù)是一個(gè)閉包华烟,閉包參數(shù)是被綁定了的視圖本身,和一個(gè)由綁定的被觀察者中所發(fā)射出來(lái)的事件元素持灰。
在RxCocoa框架中盔夜,UILable中的text
屬性是這樣實(shí)現(xiàn)的:
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這個(gè)東西很有用的,可以用來(lái)創(chuàng)建我們自己的監(jiān)聽(tīng)者堤魁。因?yàn)橛袝r(shí)候RxCocoa給的擴(kuò)展不夠我們使用喂链,比如一個(gè)UITextField有個(gè)isEnabled屬性,我想把這個(gè)isEnabled變?yōu)橐粋€(gè)observer妥泉,我們可以這樣做:
extension Reactive where Base: UITextField {
var inputEnabled: UIBindingObserver<Base, Bool> {
return UIBindingObserver(UIElement: self.base) { textField, enabled in
textField.isEnabled = enabled
}
}
}
// 當(dāng)textField1輸入的字符長(zhǎng)度大于3時(shí)椭微, 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的另外一個(gè)用得比較多的重載方法是:
bindTo(_ variable: RxSwift.Variable<Self.E>) -> Disposable
盲链,這個(gè)方法將一個(gè)被觀察者與一個(gè)Variable(變量)綁定在一起蝇率,這個(gè)變量的元素類(lèi)型跟被觀察者的事件元素類(lèi)型一致。此方法作用就是把從被觀察者事件流中發(fā)射出的事件元素存入變量中刽沾。