在開始學習 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 就會提示兩個函數:
再也不須要像 OC 同樣定義幾個函數。
Rx 表示訂閱的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,具體使用就再也不介紹。提一下新手很容易忽略的語法糖。spa
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) })
剛開始的時候可能有點看不明白,慢慢的還原閉包的語法,以後看多了就會熟悉的。