RxSwift 基本入門
RxSwift 初心者入門
在之前我們稍微提過
RxSwift
這一個framework
,也有稍微介紹了什麼是Reactive Programming
,那這邊就來詳細談談如何學習以及使用RxSwfit
吧。
使用 RxSwift 的 Playground
首先我們先至 RxSwift Clone
整個 Project
,接著我們這邊使用 Rx.Playground
做為入門的教學,按照官網的操作如下
1 | To use playgrounds: |
為什麼我們需要使用 RxSwift
我們編寫的大多數程式碼都會設計外部事件的響應。當一個使用者操控一個控制元件,我們需要寫一個
@IBAction
的對應處理。我們需要觀察鍵盤的位置的改變。當 URL sessions 回傳數據時,我們必須提供一個閉包去接受相對應的資料。我們使用KVO
去檢測變數的變化。所有的這些各式各樣系統的變化使得我們必須去撰寫相對應的代碼,而使得我們的程式碼變的臃腫且複雜,如果有一個一致的系統處理我們所有的呼叫/響應的代碼,這樣我們的程式會不會變得更優雅且美好?Rx是這樣的一個系統,RxSwfit是一個建立在Swift語言上的官方實現版本。
核心概念
Every Observable instance is just a sequence.
每一個 Observable 就只是一個序列而已。
觀察者模式 Observer Pattern
和序列 sequence
本質上是等價的,這在整個 Rx 框架(不僅只限於RxSwift)是很重要的一個基本概念。
Observable
相比 Swift
自帶的 Sequence
優勢在於,RxSwift
的 Observable
可以非同步的接受元素或者對象,這是整個 RxSwift
的核心。
- 一個
Observable
(ObservableType
) 相當於一個Sequence
。 ObservableType.subscribe(_:)
相等於Sequence.makeIterator()
。- Observer(callback)需要傳遞給ObservableType.subscribe方法來接受序列裡的元素,代替在返回的
generator
上呼叫next()
方法。
關於 Observable
在 ReactiveX 中,
Observable<Element>
代表的是一個可觀察序列,從字面意思可以看出這是在觀察者模式中的被觀察者,它會向觀察對象發送事件序列:
- next(Element) : 新事件。
- error(ErrorType) : 帶有異常的事件完成序列。
- completed() : 正常事件完結序列。
假如一個 Observable
發射一個 next
事件 ( Event.next(Element)
),那它能夠繼續發射更多的事件,假如 Observable
發射一個 error
事件(Event.error(ErrorType))
或者一個 completed
事件 (Event.completed)
,那麼這個 Observable
將再也不能發送事件給訂閱者。
Observable
的序列概念,我們可以很容易地對他做出可視化, 像是下列的序列依樣。
一個簡單的數字序列,|
符號代表正常中斷。
1 | --1--2--3--4--5--6--|----> // "|" = Terminates normally |
一個字串序列,X
符號代表錯誤中斷
1 | --a--b--c--d--e--f--X----> // "X" = Terminates with an error |
也有可能是無限的序列,像是一個按鈕的操作序列
1 | --tap--tap----------tap--> // "|" = Continues indefinitely, such as a sequence of button taps |
上面這些示意圖都被稱為 marble diagram
,這邊有更多的 marble diagram
示意圖 :
一個 Observable 的簡單例子
Observable
除非有訂閱者,否則不會執行他們的subscription closure
下面的例子,
Observable
的closure
永遠不會被執行,因為沒有任何訂閱者。(Rx.Playground
中運行的範例)
1 | example("Observable with no subscribers") { |
輸出結果 :
1 | --- Observable with no subscribers example --- |
在下面的例子,
closure
當subscribe(_:)
被調用時執行。
1 | example("Observable with subscriber") { |
輸出結果 :
1 | --- Observable with subscriber example --- |
這邊先不關心如何建立這些 Observable
的細節,我們將在後面會提到。