在開始學習 RxSwift 以前,必定要對 Swift 相關語法有所瞭解,不然就很難理解爲何能夠這樣。關於 Swift 的學習其實只要看看 Swift 的官方文檔就可夠了。我以前也列過一些學習資源:來自一線開發者的Swift學習資源推薦。
如今開始進入正題。編程
想一個有趣的問題,爲何沒有 RxObjc 呢?
實際上響應式的編程框架對語言仍是有些要求的,固然 OC 確實也有一個奠定式的 FRP 框架 ReactiveCocoa。可是客觀的說,在 Swift 裏響應式的框架寫起來會愉快的多,或者說更能發揮出語言的優點。
Swift 契合響應式有如下幾點:swift
Swift 中的枚舉(Enum)能力相比 OC 能夠說獲得了昇華。再也不只是一個相似預編譯時的宏,而是一個完整的類型。和 Struct 同樣,能夠給他定義初始化方法,聲明函數,添加擴展。一樣的泛型一樣也試用於 Enum。
枚舉還有一項神奇的能力叫關聯值。一個枚舉能夠的值能夠是不一樣的類型。官方手冊裏的示例代碼以下:閉包
enum ServerResponse {
case result(String, String)
case failure(String)
}
let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")
switch success {
case let .result(sunrise, sunset):
print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
print("Failure... \(message)")
}複製代碼
每一個 case 能夠攜帶不一樣的類型,而且能夠不止是一個值。
當 Enum 結合泛型,就發生了有趣的事。直接貼代碼:併發
enum OptionalValue<Wrapped> {
case none
case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)複製代碼
這就是 Swift 中的 Optional 實現的相似代碼。使用枚舉實現,表示值有兩種可能:沒有值的 .none 和是 Wrapped 類型的 .some。
有了以上的知識咱們再來看 Rx 中的事件流中的值Event
:app
public enum Event<Element> {
/// Next element is produced.
case next(Element)
/// Sequence terminated with an error.
case error(Swift.Error)
/// Sequence completed successfully.
case completed
}複製代碼
每一次事件的值有三種可能:1.值(next),2.完成結束(completed),3.失敗(error)。框架
若是函數在聲明時設置了一個默認值,那麼在調用時這個參數就能夠不傳。
假設咱們給 Int 定義個擴展方法increment
。若是不傳入值則默認加1,若是傳入就按照傳入的值增長:函數
extension Int {
func increment(with number: Int = 1) -> Int {
return self + number
}
}複製代碼
使用的時候 Xcode 就會提示兩個函數:
學習
subscribe
函數,有時只要寫
onNext
,有時只要寫
onError
,就是由於這個函數在聲明時同時指定了默認參數:
extension ObservableType {
public func subscribe(file: String = #file,line: UInt = #line, function: String = #function, onNext: ((E) -> Void)? = nil,
onError: ((Swift.Error) -> Void)? = nil,
onCompleted: (() -> Void)? = nil,
onDisposed: (() -> Void)? = nil)-> Disposable {
// ...
}複製代碼
能夠看到這個函數爲訂閱每一個事件可能都聲明瞭默認參數,因此你在訂閱時能夠只訂閱本身關注的訂閱。優化
閉包的使用相似 OC 中的 block,具體使用就再也不介紹。提一下新手很容易忽略的語法糖。ui
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})複製代碼
s1 和 s2 的類型和返回值類型 Xcode 能夠推斷出來能夠省略:reversedNames = names.sorted(by: { (s1, s2) in
return s1 > s2
})複製代碼
return
reversedNames = names.sorted(by: {
(s1, s2) in s1 > s2
})複製代碼
reversedNames = names.sorted(by: { $0 > $1 })複製代碼
reversedNames = names.sorted(by: >)複製代碼
當參數的最好一個參數是閉包時,能夠直接把最後一個閉包的實現跟在函數後面。
直接貼代碼表示:
// 一個最後一個參數是閉包的函數
func someFunctionThatTakesAClosure(closure: () -> Void) {
// function body goes here
}
// 默認的調用方法
someFunctionThatTakesAClosure(closure: {
// closure's body goes here
})
// 省略最後一個參數的方法名,而且把閉包的實現直接跟在函數後面
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}複製代碼
這種寫法簡化了代碼,讓代碼看起來更簡潔。
Rx 中的數據流操做符能夠靈活的組織閉包,常常會用到簡化的閉包的語法。
Observable.of(1, 2, 3, 4, 5, 6)
.filter { $0 % 2 == 0}
.subscribe(onNext: {
print($0)
})複製代碼
剛開始的時候可能有點看不明白,慢慢的還原閉包的語法,以後看多了就會熟悉的。
歡迎關注個人微博:@沒故事的卓同窗