ReactiveCocoa 4 圖解之六——信號(hào)發(fā)生器(SignalProducer)

一個(gè)信號(hào)發(fā)生器,由SignalProducer類(lèi)型表示,可以創(chuàng)建信號(hào)(signals)并施加副作用(side effects)。

信號(hào)發(fā)生器用來(lái)表示操作或者任務(wù),比如網(wǎng)絡(luò)請(qǐng)求,每一次對(duì)它調(diào)用start()將會(huì)生成一個(gè)新的后臺(tái)操作,并允許調(diào)用者監(jiān)視它的結(jié)果。另一種形式的startWithSignal()方法,會(huì)給出產(chǎn)生的信號(hào),允許在必要的情況下被監(jiān)聽(tīng)多次。

根據(jù)start()方法的動(dòng)作方式,被同一個(gè)信號(hào)發(fā)生器生成的信號(hào)可能會(huì)有不同的事件順序或版本,甚至事件流完全不一樣!和普通的信號(hào)不同,在監(jiān)聽(tīng)器連接上之前,信號(hào)發(fā)生器不會(huì)開(kāi)始工作(也就沒(méi)有事件會(huì)生成),并且在每一個(gè)新的監(jiān)聽(tīng)器連接上時(shí)其工作都會(huì)重新開(kāi)始。

啟動(dòng)一個(gè)信號(hào)發(fā)生器會(huì)返回一個(gè)存根(disposable),它可用來(lái)打斷或取消被生成信號(hào)的工作。

和信號(hào)一樣,信號(hào)生成器可以通過(guò)mapfilter等原函數(shù)操作。使用lift方法,所有信號(hào)的原函數(shù)可以被提升成為以信號(hào)生成器為對(duì)象的操作。除此以外,還有一些用來(lái)控制何時(shí)與如何啟動(dòng)信號(hào)生成器的原函數(shù),比如times

—— ReactiveCocoa 框架概覽

1. 信號(hào)發(fā)生器什么樣



簡(jiǎn)單地講,信號(hào)發(fā)生器就是一個(gè)制造信號(hào)的方法。在信號(hào)發(fā)生器內(nèi)部,這個(gè)方法稱(chēng)為啟動(dòng)處理器(startHandler),它是信號(hào)發(fā)生器僅有的數(shù)據(jù)成員:

public struct SignalProducer<Value, Error: ErrorType> {

    public typealias ProducedSignal = Signal<Value, Error>

    private let startHandler: (Signal<Value, Error>.Observer, CompositeDisposable) -> ()

    ......
}

也就是說(shuō),信號(hào)發(fā)生器看起來(lái)是這樣的:

?信號(hào)發(fā)生器是這樣的

2. 創(chuàng)建信號(hào)發(fā)生器



信號(hào)發(fā)生器的初始化函數(shù)同樣十分簡(jiǎn)單,就是將我們提供的參數(shù)作為啟動(dòng)處理器保存起來(lái):

public struct SignalProducer<Value, Error: ErrorType> {

    ......

    public init(_ startHandler: (Signal<Value, Error>.Observer, CompositeDisposable) -> ()) {
        self.startHandler = startHandler
    }

    ......
}

為了更順利地討論后面的內(nèi)容,我們?cè)诖思s定:信號(hào)發(fā)生器制造出來(lái)的信號(hào)稱(chēng)為結(jié)果信號(hào)(produced signal)。

現(xiàn)在要看看我們的任務(wù)了:定義啟動(dòng)處理器。啟動(dòng)處理器的主要內(nèi)容,就是定義結(jié)果信號(hào)的事件源。它會(huì)在信號(hào)發(fā)生器每次啟動(dòng)時(shí)被調(diào)用,也就是說(shuō),結(jié)果信號(hào)只有在信號(hào)發(fā)生器啟動(dòng)時(shí)才會(huì)生成,而且每一次啟動(dòng)信號(hào)生成器都會(huì)得到一個(gè)新的結(jié)果信號(hào),只不過(guò)這些結(jié)果信號(hào)的事件源工作方式相同(但產(chǎn)生的事件不一定相同)。

啟動(dòng)處理器是一個(gè)簽名為(Observer, CompositeDisposable) -> ()的方法,第一個(gè)參數(shù)就是結(jié)果信號(hào)(即將被制造的信號(hào))的事件分發(fā)器,如果我們向這個(gè)分發(fā)器發(fā)送事件的話(huà),結(jié)果信號(hào)的監(jiān)聽(tīng)器就會(huì)收到。

3. 啟動(dòng)信號(hào)發(fā)生器



啟動(dòng)信號(hào)發(fā)生器,可以調(diào)用信號(hào)發(fā)生器對(duì)象的startWithSignal(setUp: (Signal, Disposable) -> ())方法,這個(gè)方法接收一個(gè)回調(diào)函數(shù)作為參數(shù),而我們必須提供這個(gè)回調(diào)函數(shù)。正如參數(shù)名稱(chēng)setUp所暗示的,這個(gè)回調(diào)函數(shù)會(huì)在信號(hào)的事件源開(kāi)始工作(也就是發(fā)送事件)之前執(zhí)行,信號(hào)的引用和一個(gè)取消用存根被交到我們手中,這給了我們一個(gè)機(jī)會(huì)做一些準(zhǔn)備工作,比如向信號(hào)添加監(jiān)聽(tīng)器,將信號(hào)變形,或者干脆通過(guò)取消用存根取消啟動(dòng)等等。

下面是startWithSignal執(zhí)行的步驟:

  1. 調(diào)用Signal類(lèi)的pipe()類(lèi)方法,得到一個(gè)信號(hào)和這個(gè)信號(hào)的事件分發(fā)器。
  2. 創(chuàng)建一個(gè)CompositeDisposable類(lèi)型的發(fā)生器存根。
  3. 創(chuàng)建一個(gè)ActionDisposable類(lèi)型的取消用存根,如果這個(gè)存根被廢棄,它會(huì)在事件分發(fā)器上發(fā)送一個(gè)Interrupted事件,之后將上一步中創(chuàng)建的發(fā)生器存根廢棄掉。
  4. 將信號(hào)和取消用存根交給回調(diào)方法setUp,執(zhí)行我們的準(zhǔn)備工作。
  5. 如果準(zhǔn)備工作后取消用存根被廢棄了,就停止處理立即返回。
  6. 將信號(hào)的事件分發(fā)器包裝在一個(gè)監(jiān)聽(tīng)器對(duì)象(wrapperObserver)中,這個(gè)監(jiān)聽(tīng)器對(duì)象會(huì)將自己接收到的所有事件原封不動(dòng)地交給事件分發(fā)器,不過(guò)一旦它接收到終結(jié)事件,它會(huì)廢棄第二步中創(chuàng)建的生成器存根。
  7. 使用上一步包裝過(guò)的監(jiān)聽(tīng)器和第二步中創(chuàng)建的發(fā)生器存根調(diào)用啟動(dòng)處理器。
啟動(dòng)后出現(xiàn)的對(duì)象,圖中藍(lán)色的箭頭表示對(duì)象間的引用關(guān)系

4. 緩沖(Buffer)

緩沖,由SignalProducer.buffer()方法創(chuàng)建,是一個(gè)事件的隊(duì)列(queue),每當(dāng)信號(hào)發(fā)生器創(chuàng)建新的信號(hào)時(shí),隊(duì)列中的事件會(huì)被重播(replay)。

和管道(pipe)相似,這個(gè)方法返回一個(gè)監(jiān)聽(tīng)器(Observer)。向這個(gè)監(jiān)聽(tīng)器發(fā)送的事件會(huì)被加入隊(duì)列中。如果在加入新的事件時(shí),隊(duì)列已經(jīng)達(dá)到最大容量(隊(duì)列長(zhǎng)度),那么為了以騰出空間,隊(duì)列中最早加入的事件會(huì)被移除。

5. Lift

Lift在做什么.png

6. 副作用

7.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,973評(píng)論 19 139
  • 一個(gè)信號(hào),由Signal類(lèi)型表現(xiàn),是可以被持續(xù)監(jiān)視的一系列事件(events)。 信號(hào)一般用來(lái)表示“正在進(jìn)行中”的...
    HetfieldJoe閱讀 4,757評(píng)論 16 21
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,462評(píng)論 25 708
  • 一個(gè)存根,用Disposable協(xié)議表示,是一個(gè)內(nèi)存管理和取消操作的機(jī)制。 當(dāng)啟動(dòng)一個(gè)信號(hào)發(fā)生器(SignalPr...
    HetfieldJoe閱讀 1,699評(píng)論 0 5
  • 早起早睡 六月作息已經(jīng)恢復(fù)正常,從23:50-6:50逐周調(diào)整到了23:10-6:10,目標(biāo)達(dá)成率93%,能從五月...
    littletree閱讀 341評(píng)論 0 1