理解Observables and Observer

通過UITextFieldrx_text屬性體會了“事件數(shù)組”的概念和用法之后,我們通過這正式向大家介紹RxSwift中的事件序列,它叫做Observables。以及如何創(chuàng)建以及訂閱Observables。

在Playground中使用RxSwift

為了能夠更方便的看到代碼的執(zhí)行結(jié)果,在這段視頻中,我們使用Playground向大家介紹RxSwift observables的用法。

首先,我們新建一個“OS X Application”,選擇“Command Line Tool”,點(diǎn)擊Next;

image

其次,設(shè)置一個項(xiàng)目名稱,例如“Understanding Observables”,然后把Language設(shè)置成“Swift”,點(diǎn)擊Next;

image

最后,給項(xiàng)目設(shè)置一個保存路徑,點(diǎn)擊Create。

然后,我們用同樣的方法使用使用CocoaPods安裝RxSwift,唯一一個不同的地方就是生成的Podfile里,我們不要對platform行取消注釋:

# Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!

target 'Understanding Observables' do
    pod 'RxSwift',    '~> 2.0'
    pod 'RxCocoa',    '~> 2.0'
end

安裝完成之后,我們用生成的.xcworkspace文件重新打開項(xiàng)目:

image

Command + B構(gòu)建一次。接下來,選中“Understanding Observables”,按Command + N(或者如下圖使用鼠標(biāo)右鍵):

image

在彈出的窗口中,選中“OS X / Source / Playground”,點(diǎn)擊Next:

image

點(diǎn)擊Create,完成添加。最后,打開新添加的Playground文件,在import Cocoa后面添加下面的代碼:

import RxSwift
import RxCocoa

如果沒有發(fā)生錯誤,就表示我們可以在Playground中使用RxSwift了。

如果Playground提示你“No such module RxSwift”,可以按Command + B重新構(gòu)建一次就好了。


創(chuàng)建Observables

接下來,我們創(chuàng)建一個最簡單的Observable對象:

let emptySequence = Observable<Int>.empty()

其中,Observable是RxSwift中的一個泛型類,Observable<Int>表示一個.Success值類型為Int(請參考我們在上一段視頻中提到過的Event enumeration中關(guān)于事件的定義)的“事件數(shù)組”。

而empty則是Observable中的一個類方法,用于創(chuàng)建一個空的事件數(shù)組,它唯一可以做的事情,就是向訂閱者發(fā)送一個Completed事件。

理解對Observables的訂閱

訂閱Observable中的事件很簡單,使用subscribe方法就可以了:

emptySequence.subscribe {
    (event: RxSwift.Event<Int>) -> Void in
        print(event)
}

subscribe方法接受一個Closure做為事件的處理函數(shù),這個Clousre接受一個RxSwift.Event<Int>類型(因?yàn)槲覀兌x的emptySequence中事件的值類型是Int)的參數(shù),表示發(fā)生的事件,返回Void

這個Closure甚至還有一個自己的名字,叫做Observer。

我們的Observer實(shí)現(xiàn)則很簡單,只是把訂閱到的事件打印在了控制臺上,從輸出的結(jié)果可以看到,我們只訂閱到了一個Completed事件。

image

這就是定義Observables以及Observer的方法。除了empty之外,RxSwift還為我們提供了一些創(chuàng)建Observables的方法,我們來看一下它們的用法。


幾種常見的Observables創(chuàng)建方法

just - 只包含一個事件的序列

just創(chuàng)建的事件序列只包含一個事件元素,當(dāng)訂閱它的時候,它向訂閱者發(fā)送兩個消息:事件值和.Completed事件。例如:

print("--- Just sequence ---")

_ = Observable.just("Boxue").subscribe({
    (event: RxSwift.Event<String>) -> Void in
        print(event)
})

在控制臺里,我們可以看到Just序列發(fā)送了兩個事件:一個是.Next,它的值是我們定義序列時指定的值“Boxue”,然后緊跟著一個.Completed事件。

image

of - 包含固定個數(shù)事件的序列

of創(chuàng)建一個可以向observer發(fā)送固定個數(shù)事件的序列,發(fā)送完成之后,發(fā)送.Completed:

print("--- Of sequence ---")

_ = Observable.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
        .subscribe({
            (event: RxSwift.Event<Int>) -> Void in
                print(event)
        })

在控制臺里,可以看到我們訂閱到了10個.Next事件,一個.Completed事件:

image

error - 只產(chǎn)生.Error事件的序列

error用于定義一個只能訂閱.Error事件的序列,例如:

let err = NSError(domain: "Test", code: -1, userInfo: nil)

_ = Observable<Int>.error(err).subscribe {
    (event: RxSwift.Event<Int>) in
        print(event)
}

在控制臺里,我們就可以看到一個錯誤事件訂閱:

image

create - 自定義的事件序列

create允許我們使用Swift closure自定義一個事件序列的構(gòu)建過程。例如,我們根據(jù)事件的值是否是偶數(shù)自定義一個事件序列:

print("--- create ---")

func myJust(event: Int) -> Observable<Int> {
    return Observable.create { observer in
        if event % 2 == 0 {
            observer.on(.Next(event))
            observer.on(.Completed)
        }
        else {
            let err =
                NSError(domain: "Not an even number", 
                    code: 401, userInfo: nil)
            observer.on(.Error(err))
        }

        return NopDisposable.instance
    }
}

在上面的例子里,有幾點(diǎn)需要特別說明:

  • create接受一個closure參數(shù),用于定義事件的發(fā)生過程,我們先暫時忽略掉它的具體簽名,只需要知道它有一個表示observer的參數(shù)就可以了;
  • 在closure的實(shí)現(xiàn)里,on和我們之前使用過的subscribe方法作用是類似的,用于向observer發(fā)送事件。當(dāng)event是偶數(shù)的時候,我們向observer發(fā)送.Next和.Complete表示成功事件并結(jié)束;否則,我們向observer發(fā)送.Error;
  • 最后,NopDisposable.instance是一個靜態(tài)類對象,表示當(dāng)create創(chuàng)建的observable被銷毀時,無需執(zhí)行任何額外操作,在下一個視頻中,我們會專門講到observable被銷毀的話題;

然后,我們可以像下面這樣來使用create定義的事件序列:

myJust(10).subscribe { print($0) }
myJust(5).subscribe { print($0) }

這樣,在控制臺,我們就能分別看到一次.Next + .Compeleted的訂閱和一次.Error的訂閱了:

image

generate - 用prev決定next的事件序列

generate可以生成一連串事件,并且,允許我們根據(jù)上一次事件的結(jié)果生成下一次事件,并設(shè)置.Completed條件:

print("--- generate ---")

_ = Observable.generate(
            initialState: 0,
            condition: { $0 < 10 },
            iterate: { $0 + 1 }
        ).subscribe {
            print($0)
        }

在這里例子里:

  • initialState用于指定事件序列的初始值,它是一個.Next(0);
  • condition是一個closure,當(dāng)它為true時,就生成.Next,否則生成.Completed;
  • iterator用于設(shè)置每一次發(fā)送事件之后,對事件值進(jìn)行的迭代操作,在我們的例子里,就是.Next的值加1;

然后,我們使用subscribe訂閱就可以在控制臺看到下面的結(jié)果了:

image

deferred - 只有在被訂閱后才創(chuàng)建并產(chǎn)生事件的序列

與其說deferred用于創(chuàng)建一個事件序列,不如說它是對創(chuàng)建序列的一種修飾。被deferred修飾后,事件序列只有在被訂閱時才生成,并發(fā)送事件,并且,每訂閱一次,就新生成一個事件序列對象。

例如,對于上面的generate例子來說:

print("--- deferred ---")
let deferredSequence = Observable<Int>.deferred {
    print("generating")

    return Observable.generate(
        initialState: 0,
        condition: { $0 < 3 },
        iterate: { $0 + 1})
}

當(dāng)我們訂閱deferredSequence時:

_ = deferredSequence.subscribe { print($0) }
_ = deferredSequence.subscribe { print($0) }

在控制臺里,我們可以看到這樣的結(jié)果:

image

這說明,deferredSequence創(chuàng)建了兩次,并且向訂閱者發(fā)送了3次.Next以及1次.Completed。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容