RXSwift-初體驗(yàn)(隨想)

為什么要學(xué)RXSwift?

有產(chǎn)生這個(gè)疑問(wèn)的同學(xué)譬圣,請(qǐng)先看下圖


??

試問(wèn),這么牛逼的框架不值得去研究一番嘛雄坪?厘熟??

(貼心奉上)點(diǎn)了我维哈,愛(ài)上我

決定要去做一件事绳姨,至少要知道原因,或者是需要一份動(dòng)力阔挠。RXSwift官網(wǎng)上列舉了一些例子簡(jiǎn)單告訴了我們RXSwift具備了哪些能力飘庄,比如說(shuō):

  • 它可以統(tǒng)一處理 Delegate, KVO,Notification
  • 它可以綁定UI
  • 方便網(wǎng)絡(luò)請(qǐng)求的處理

等等一系列能力......

但這些也只是描述了可以用RXSwift可以來(lái)做什么,而我們更關(guān)注的是為什么要選擇RXSwift?

關(guān)于這一點(diǎn)我們需要分析下GUI 編程的本質(zhì)

GUI可以抽象為視圖和數(shù)據(jù)的結(jié)合

視圖負(fù)責(zé)兩件事:展示和交互购撼,而展示什么由數(shù)據(jù)決定跪削!

上圖可以看到RxSwift可以在UniDirectional Data Flow的各個(gè)階段都發(fā)揮作用,從而讓Data 的處理和流動(dòng)更加簡(jiǎn)潔和清晰迂求!

具體解釋如下:

  • 通過(guò)對(duì)RxCocoa的各種回調(diào)進(jìn)行統(tǒng)一處理碾盐,方便了「Interact」的處理。
  • 通過(guò)對(duì)Observabletransformcomposite揩局,方便了 「Action」的生成(比如使用throttle來(lái)壓縮Action)毫玖。
  • 通過(guò)對(duì)網(wǎng)絡(luò)請(qǐng)求以及其他異步數(shù)據(jù)的獲取進(jìn)行Observable封裝,方便了異步數(shù)據(jù)的處理。
  • 通過(guò)RxCocoabinding孕豹,方便了數(shù)據(jù)的渲染涩盾。

綜上我們能看到

RxCocoa規(guī)范了數(shù)據(jù)流RxSwift為數(shù)據(jù)的處理提供了方便励背,這兩個(gè)類(lèi)庫(kù)的結(jié)合春霍,可以產(chǎn)生清晰的架構(gòu)和易維護(hù)的代碼

RXSwift所為何物?

在說(shuō)RxSwift之前叶眉,先來(lái)說(shuō)下Rx址儒, ReactiveX 是一種編程模型,最初由微軟開(kāi)發(fā)衅疙,結(jié)合了觀察者模式莲趣、迭代器模式和函數(shù)式編程的精華,來(lái)更方便地處理異步數(shù)據(jù)流饱溢。其中最重要的一個(gè)概念是 Observable喧伞。

在這里有個(gè)比較好的例子幫助理解這個(gè)Observable

“舉個(gè)簡(jiǎn)單的例子,當(dāng)別人在跟你說(shuō)話(huà)時(shí)绩郎,你就是那個(gè)觀察者潘鲫,別人就是那個(gè) Observable,它有幾個(gè)特點(diǎn):

  • 可能會(huì)不斷地跟你說(shuō)話(huà)肋杖。(onNext:
  • 可能會(huì)說(shuō)錯(cuò)話(huà)溉仑。(onError:
  • 結(jié)束會(huì)說(shuō)話(huà)。(onCompleted

你在聽(tīng)到對(duì)方說(shuō)的話(huà)后状植,也可以有幾種反應(yīng):

  • 根據(jù)說(shuō)的話(huà)浊竟,做相應(yīng)的事,比如對(duì)方讓你借本書(shū)給他津畸。(subscribe
  • 把對(duì)方說(shuō)的話(huà)振定,加工下再傳達(dá)給其他人,比如對(duì)方說(shuō)小張好像不太舒服肉拓,你傳達(dá)給其他人時(shí)就變成了小張失戀了吩案。(map:
  • 參考其他人說(shuō)的話(huà)再做處理,比如 A 說(shuō)某家店很好吃帝簇,B 說(shuō)某家店一般般徘郭,你需要結(jié)合兩個(gè)人的意見(jiàn)再做定奪。(zip:)”

在這里核心當(dāng)數(shù)據(jù)有變化時(shí)丧肴,能夠立刻知曉残揉,并且通過(guò)組合和轉(zhuǎn)換后,可以即時(shí)作出響應(yīng)芋浮。

RXSwift工作流抱环?

在了解了RXSwift后壳快,我們自然而然的就會(huì)想它具體的工作流程是什么呢?

其實(shí)大致可以分為這么幾個(gè)階段:

  • 先把 Native Object 變成Observable
    |
  • 通過(guò) Observable 內(nèi)置的各種強(qiáng)大的轉(zhuǎn)換和組合能力變成新的 Observable
    |
  • 最后消費(fèi)新的 Observable 的數(shù)據(jù)

可以參考下圖來(lái)理解:


RXSwift工作流

Native Object -> Observable

  • rx extension
    可以說(shuō)“萬(wàn)物皆可RX”镇草,直接上圖
萬(wàn)物皆可RX
萬(wàn)物皆可RX

看到這里眶痰,無(wú)需多言了吧。梯啤。

Observable.create

通過(guò)這個(gè)方法竖伯,可以將 Native object 包裝成 Observable

  public static func create(_ subscribe: @escaping (AnyObserver<E>) -> Disposable) -> Observable<E> {
        return AnonymousObservable(subscribe)
    }
  • Variable()
    Variable(value)可以把 value 變成一個(gè) Observable

我們可以點(diǎn)擊到它里面看一下

public final class Variable<Element> {

    public typealias E = Element

    private let _subject: BehaviorSubject<Element>

    private var _lock = SpinLock()

    // state
    private var _value: E

    #if DEBUG
    fileprivate let _synchronizationTracker = SynchronizationTracker()
    #endif

    /// Gets or sets current value of variable.
    ///
    /// Whenever a new value is set, all the observers are notified of the change.
    ///
    /// Even if the newly set value is same as the old value, observers are still notified for change.
    public var value: E {
        get {
            self._lock.lock(); defer { self._lock.unlock() }
            return self._value
        }
        set(newValue) {
            #if DEBUG
                self._synchronizationTracker.register(synchronizationErrorMessage: .variable)
                defer { self._synchronizationTracker.unregister() }
            #endif
            self._lock.lock()
            self._value = newValue
            self._lock.unlock()

            self._subject.on(.next(newValue))
        }
    }

    /// Initializes variable with initial value.
    ///
    /// - parameter value: Initial variable value.
    public init(_ value: Element) {
        #if DEBUG
            DeprecationWarner.warnIfNeeded(.variable)
        #endif

        self._value = value
        self._subject = BehaviorSubject(value: value)
    }

    /// - returns: Canonical interface for push style sequence
    public func asObservable() -> Observable<E> {
        return self._subject
    }

    deinit {
        self._subject.on(.completed)
    }
}

就會(huì)發(fā)現(xiàn)是它通過(guò) subject來(lái)做的,大意是value存到一個(gè)內(nèi)部變量_value 里因宇,當(dāng)調(diào)用 value方法時(shí)七婴,先更新_value值,然后調(diào)用內(nèi)部的_subject.on(.next(newValue))方法告知 subscriber

  • Subject

Subject簡(jiǎn)單說(shuō)是一個(gè)可以主動(dòng)發(fā)射數(shù)據(jù)的Observable察滑,多了 onNext(value), onError(error), ‘onCompleted’方法!

let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
    
subject.addObserver("1").addDisposableTo(disposeBag)
subject.onNext("AAA")
subject.onNext("BBB")
    
subject.addObserver("2").addDisposableTo(disposeBag)
subject.onNext("??????")
subject.onNext("??????")

Subject還是建議少用打厘,雖然官方并沒(méi)有提及,但因?yàn)樵谝郧笆褂肦AC的時(shí)候贺辰,Subject 因其本身功能太過(guò)強(qiáng)大户盯,不好控制,成了一個(gè)不太推薦使用的功能饲化,

  • Observable -> New Observable

Observable ----(修改/過(guò)濾/組合等操作)----> New Observable

換言之先舷,Observable可以隨心所欲構(gòu)造自己想要的數(shù)據(jù)~!

  • Combine
    Combine 就是把多個(gè) Observable組合起來(lái)使用

  • Transform
    對(duì)一個(gè) Observable 的數(shù)值做一些小改動(dòng)滓侍,產(chǎn)出新的值,依是 Observable

let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
    .map { $0 * $0 }
    .subscribe(onNext: { print($0) })
    .addDisposableTo(disposeBag)
  • Filter
    Filter的作用是對(duì) Observable 傳過(guò)來(lái)的數(shù)據(jù)進(jìn)行過(guò)濾牲芋,只有符合條件的才有資格被subscribe

結(jié)語(yǔ)

上面只是簡(jiǎn)單介紹了RXSwift相關(guān)的一些基本概念撩笆,其實(shí)這些如果理清楚了,你會(huì)發(fā)現(xiàn)RXSwift并不難(尤其是具備RAC開(kāi)發(fā)經(jīng)驗(yàn)的)缸浦,要習(xí)慣多去從Observable的角度分析思考問(wèn)題夕冲,慢慢的就會(huì)領(lǐng)略到函數(shù)響應(yīng)式編程的真正魅力了,同時(shí)自身的抽象能力和代碼可讀性都會(huì)有提升裂逐。

學(xué)習(xí)技術(shù)我個(gè)人覺(jué)得掌握其核心思想最重要歹鱼,因?yàn)樗强梢蕴嵘銈€(gè)人認(rèn)知能力的~!

這不僅僅可以幫助你解決技術(shù)問(wèn)題卜高,也可以在你生活中遇到問(wèn)題時(shí)弥姻,提供解決思路~!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掺涛,一起剝皮案震驚了整個(gè)濱河市庭敦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌薪缆,老刑警劉巖秧廉,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疼电,警方通過(guò)查閱死者的電腦和手機(jī)嚼锄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蔽豺,“玉大人区丑,你說(shuō)我怎么就攤上這事∶K洌” “怎么了刊苍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)濒析。 經(jīng)常有香客問(wèn)我正什,道長(zhǎng),這世上最難降的妖魔是什么号杏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任婴氮,我火速辦了婚禮,結(jié)果婚禮上盾致,老公的妹妹穿的比我還像新娘主经。我一直安慰自己,他們只是感情好庭惜,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布罩驻。 她就那樣靜靜地躺著,像睡著了一般护赊。 火紅的嫁衣襯著肌膚如雪惠遏。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天骏啰,我揣著相機(jī)與錄音节吮,去河邊找鬼。 笑死判耕,一個(gè)胖子當(dāng)著我的面吹牛透绩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壁熄,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帚豪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了草丧?” 一聲冷哼從身側(cè)響起志鞍,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎方仿,沒(méi)想到半個(gè)月后固棚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體统翩,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年此洲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厂汗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呜师,死狀恐怖娶桦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汁汗,我是刑警寧澤衷畦,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站知牌,受9級(jí)特大地震影響祈争,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜角寸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一菩混、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扁藕,春花似錦沮峡、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至望薄,卻和暖如春疟游,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背式矫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留役耕,地道東北人采转。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瞬痘,于是被迫代替她去往敵國(guó)和親故慈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345