1. 程式人生 > 其它 >RxSwift學習(一) --- RxSwift介紹

RxSwift學習(一) --- RxSwift介紹

技術標籤:swiftRxSwiftRxSwiftSwiftswift

函式響應式式程式設計(FRP)

函數語言程式設計(FP)

函數語言程式設計就是一種抽象程度很高的程式設計正規化,它將計算機運算看做是數學中函式的計算,而純粹的函數語言程式設計語言編寫的函式沒有變數,因此,任意一個函式,只要輸入是確定的,輸出就是確定的,這種純函式我們稱之為沒有副作用

簡單來說: 將函式作為一個單元來處理邏輯,給定一個輸入值,就會有對應的一個輸出值。函式還可以作為引數和返回值。這就是函式程式設計。

函式表示式: y = f(x) —> x = f(x) —> y = f(f(x))

函式程式設計的特性

  • 閉包: 一種特殊的函式,綁定了函式內部引用的所有變數,把它引用的東西都放在一個上下文中“包”了起來
  • 高階函式: 把函式作為引數或者返回值的函式
  • 匿名函式: 在傳入函式時,有些時候,不需要顯式地定義函式,可以直接傳入匿名函式。
  • 柯里化: 把接受多個引數的函式變換成接受一個單一引數(最初函式的第一個引數)的函式,並且返回接受餘下的引數且返回結果的新函式的技術

優點

  • 惰性
  • 遞迴
響應式程式設計 (RP)

響應式程式設計是一種從資料流和變化出發的解決問題的模式。 響應式程式設計,本質上是對資料流或某種變化所作出的反應,但是這個變化什麼時候發生是未知的,所以是基於非同步、回撥的方式在處理問題。

通俗來講:A賦值給BB發生變化的時候A也會跟著發生變化,這就是響應式程式設計。

響應式程式設計

  • 資料流: 一個流就是一串事件發生的時間的值的序列。這裡面至少有三要素:資料報錯完成.
  • 變化: 訊號變化回撥
函式響應式程式設計(FRP)

函式響應式程式設計:說白了就是函式式和響應式的結合.

RxSwift 介紹

RxSwift: 是 Rx 為 Swift 語言開發的一門函式響應式程式語言, 它可以代替iOS系統的 Target Action / 代理 / 閉包 / 通知 / KVO,同時還提供網路、資料繫結、UI事件處理、UI的展示和更新、多執行緒……

在RxSwift中,所有非同步操作(事件)和資料流均被抽象為可觀察序列的概念

RxSwift的主要流程: 建立序列 --> 訂閱序列 --> 傳送訊號 --> 訊號接收

一、RxSwift 配置

  1. 使用RxSwift需要匯入RxSwiftRxCocoa 這兩個庫,缺一不可。這兩個庫的主要作用是:
  • RxSwift:它只是基於 Swift 語言的Rx 標準實現介面庫,所以 RxSwift 裡不包含任何 Cocoa 或者 UI 方面的類
  • RxCocoa:是基於 RxSwift 針對於 iOS 開發的一個庫,它通過 Extension 的方法給原生的比如 UI 控制元件添加了 Rx 的特性,使得我們更容易訂閱和響應這些控制元件的事件。
  1. 再使用RxSwift的地方import這個兩個庫就行
import RxSwift
import RxCocoa

二、Observable (建立、訂閱、銷燬)

1、Observable
  • Observable<T>: 觀察序列

1、Observable 這個類就是 Rx 框架的基礎,我們可以稱它為可觀察序列。它的作用就是可以非同步地產生一系列的 Event(事件),即一個 Observable 物件會隨著時間推移不定期地發出 event(element : T) 這樣一個東西。
2、這些 Event 還可以攜帶資料,它的泛型 就是用來指定這個 Event 攜帶的資料的型別。
3、有了可觀察序列,我們還需要有一個 Observer(訂閱者)來訂閱它,這樣這個訂閱者才能收到 Observable 不時發出的 Event。

  • Enevt: 事件。
    Observable可以發出三種不同的事件:nexterrorcompleted
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: next 事件就是那個可以攜帶資料 <T> 的事件
2、error: error事件表示一個錯誤,它可以攜帶具體的錯誤內容,一旦 Observable 發出了 error event,則這個 Observable 就等於終止了,以後它再也不會發出 event 事件了
3、completed: completed 事件表示 Observable 發出的事件正常地結束了,一旦 Observable 發出了completed event,則這個 Observable 就等於終止了,以後它再也不會發出 event 事件了

2、Observable 序列的建立

Observable有好多種序列的建立方法,我們這裡就解說一種比較常用的create() 序列建立,其他常見的可以參考Observable 常見的序列建立方法

create 序列

  • 該方法接受一個 閉包形式的引數,任務是對每一個過來的訂閱進行處理。
  • 下面是一個簡單的樣例。為方便演示,這裡增加了訂閱相關程式碼
  • 這也是序列建立的一般方式,應用非常之多
// 1、建立序列
_ = Observable<String>.create({ (observable) -> Disposable in
            //3、傳送訊號
            observable.onNext("RxSwift  你好!")
//            observable.onError()  //傳送錯誤訊號
//            observable.onCompleted() //傳送完成訊號
            
            return Disposables.create() // 銷燬
           // 2、訂閱序列
        }).subscribe(onNext: { (next) in
            NSLog("訂閱到--\(next)")
        }, onError: { (error) in
            NSLog("錯誤--\(error)")
        }, onCompleted: {
            NSLog("完成回撥")
        }, onDisposed: {
            NSLog("訂釋放回調")
        })
3、Observable 訂閱

一般我們建立完Observable 序列以後,我們會用subscribe()對其進行訂閱,用來接收Observable發出的事件Event .
關於subscribe的訂閱有兩種方式:

  • subscribe()方法:該方法的 block 的回撥引數就是被髮出的 event 事件,我們將其直接打印出來。
let observable = Observable<String>.of("Json","XML")

observable.subscribe { (event) in
                    Log("---of----\(event)")
                }.disposed(by: self.disposeBag)

// 列印值
//ofQueue():73->---of----next(Json)
//ofQueue():73->---of----next(XML)
//ofQueue():73->---of----completed

1、初始化 Observable 序列時設定的預設值都按順序通過 .next事件傳送出來
2、next事件送完以後,還會自動傳送一個completed事件
3、我們要向獲取接收到的元素可以用event.element 去獲取

  • subscribe的另一種訂閱方法:該方法可以把 event 進行分類,通過不同的 block 回撥處理不同型別的 event,同時會把 event 攜帶的資料直接解包出來作為引數,方便我們使用。
	let observable = Observable<String>.of("Json","XML")
              
     observable.subscribe { (element) in
          print("---of----\(element)")
     } onError: { (error) in
          print(error)
     } onCompleted: {
          print("completed")
     } onDisposed: {
          print("disposed")
     }
     
    // 列印
    //---of----Json
	//---of----XML
	//completed
	//disposed

1、我們通過打印發現這次直接列印的是element,不需要event.element處理了
2、每個回撥都獨立出來了,我們可以做一些不同的業務需求

4、監聽事件的生命週期

關於事件的生命週期,我們可以用doOn來監聽,關於doOn:

  • doOn 方法的呼叫不會影響subscribe的呼叫
  • doOn 方法會在每一次事件傳送前被呼叫
  • 同時它和 subscribe 一樣,可以通過不同的 block 回撥處理不同型別的 event

doOn的每個回撥都發生在subscribe之前
do(onNext:)方法在 subscribe(onNext:) 前呼叫
do(onCompleted:) 方法在 subscribe(onCompleted:) 前面呼叫
do(onDisposed)銷燬方法卻是在subscribe(onDisposed)後面呼叫的

let observable = Observable<String>.of("Json","XML")
       
        observable
            .do(onNext: { element in
                print("---do---\(element)" )
            }, onError: { error in
                print("do Error:", error)
            }, onCompleted: {
                print("do Completed")
            }, onDispose: {
                print("do Disposed")
            })
            .subscribe { (element) in
                print("---of---\(element)")
            } onError: { (error) in
                print(error)
            } onCompleted: {
                print("completed")
            } onDisposed: {
                print("disposed")
            }
        列印
       // ---do---Json
       // ---of---Json
       // ---do---XML
       // ---of---XML
       // do Completed
       // completed
        //disposed
       // do Disposed
5、Observable 的銷燬(Dispose)

當一個Observable被觀察訂閱後,就會產生一個Disposable例項,通過這個例項,我們就能進行資源的釋放了。
對於RxSwift中資源的釋放,也就是解除繫結、釋放空間,有兩種方法,分別是顯式釋放隱式釋放

  • 顯式釋放: 也就是dispose(), 可以讓我們在程式碼中直接呼叫釋放方法進行資源的釋放
let dispose =  self.TestButton.rx.tap.subscribe({ _ in
            NSLog("點選")
        })
 dispose.dispose()
  • 隱式釋放
    隱式釋放則通過DisposeBag來進行,它類似於Objective-C ARC中的自動釋放池機制.
    DisposeBag對於RxSwift就像自動釋放池一樣,我們把資源新增到DisposeBag中,讓資源隨著DisposeBag一起釋放。

DisposeBag就像個垃圾袋一樣,我們把建立的序列放在DisposeBag這個垃圾袋中,他會在合適的時候幫我們釋放資源。

// 可以寫成全域性的
static var disposeBag = DisposeBag()

let observable = Observable<String>.of("Json","XML")
    observable
            .subscribe { (event) in
                    Log("---of----\(event)")
            }.disposed(by: self.disposeBag)