iOS響應式編程:ReactiveCocoa vs RxSwift 選誰好

內容來自stack overflow的一個回答:ReactiveCocoa vs RxSwift - pros and cons?

要直接比較這兩個有點難。Rx 是 Reactive Extensions 的一部分眷蜓,其他語言像C#, Java 和 JS 也有葡盗。Reactive Cocoa 受 Functional Reactive Programming(FRP) 啟發(fā),但是在最近一段時間里方援,他們提到也受到Reactive Extensions的啟發(fā)酝陈。最終結果就是一個從Rx借鑒了一些東西营罢,但是有著源自FRP名聲的一個框架。

第一點要說明的事是無論是RAC還是Rx都不是真正意義上的Functional Reactive Programming仲智。按照 What is (functional) reactive programming 里的回答對于FRP概念的定義买乃。有了這個認識,我們就可以從兩個框架如何處理subscribing/observing時的副作用(side effect)和一些其他的組件上兩個方面來比較钓辆。

我們來看看社區(qū)(community)和技術實現(xiàn)(extra-tech)剪验。

RAC是一個已經(jīng)有著3年歷史的項目,從Objective-C時期開始前联,后來從3.0開始支持了swift(可以通過bridge在OC下使用)功戚,接著就完全停止了在Objective-C上的維護。RxSwift項目的時間短一些只有幾個月(作者寫的時間是15年)似嗤,但是社區(qū)似乎充滿了動力啸臀。關于RxSwift有一件重要的事是項目是按照 ReactiveX這個組織的規(guī)定下開發(fā)的,并且所有其他語言的Rx項目也是一樣烁落。如果學會了如何使用RxSwift乘粒,再去學習Rx.Net, RxJava 或者 RxJS就是小菜一碟,只是語言語法上的差異伤塌。這真的就是learn once, apply everywhere.

再來看看技術實現(xiàn)谓厘。

Producing/Observing Entities

RAC 3.0主要有兩個實體,<code>signal</code> 和 <code> SignalProducer </code>寸谜。第一個發(fā)布事件無論是否有綁定訂閱者竟稳,后者要有一個信號或者事件產(chǎn)生才會觸發(fā)。這兩個區(qū)別是為了區(qū)分冷信號和熱信號熊痴,也使很多開發(fā)者困惑他爸。這就是他們處理副作用的一大區(qū)別。

在RxSwift果善,<code>signal</code> 和 <code> SignalProducer </code>變成了<code> Observable </code>诊笤,聽起來有點困惑,但是這兩個實體在Rx的世界里是同一個東西巾陕。在RxSwift里創(chuàng)建Observables不需要考慮是冷信號還是熱信號讨跟,一旦你理解了他們的工作原理就很容易掌握。再次說明 冷/熱(cold/hot/warm)信號就是當你subscribing/observing 產(chǎn)生的副作用鄙煤。

對于訂閱的概念兩者基本是一樣的晾匠。在RAC里有一點小的區(qū)別,RAC可以中斷一個事件當信號被 <code> disposed </code>梯刚,即使在事件發(fā)送完成信號之前凉馆。總結一下兩者都有的以下事件:

  • <code> Next </code>
    處理新收到的值
  • <code> Error </code>
    處理一個錯誤,結束整個流澜共,對所有的觀察者取消訂閱
  • <code> Complete </code>
    標記整個流已經(jīng)完成向叉,取消所有觀察者的訂閱
    另外RAC會在收到一個disposed Signal后中斷,即使沒有收到complete或者error嗦董。

Manually Writing

在RAC中母谎,Signal/SignalProducer都是只讀的實體,他們不能從外部被改變京革,RxSwift中的Observable也是如此销睁。如果要把Signal/SignalProducer改變成可以手動改寫的實體,你只能通過調用<code>pipe()</code>函數(shù)返回一個可以改動的對象存崖。在Rx中冻记,這是一個不同的類型叫做<code>Subject</code>。
如果讀/寫這樣的概念聽起來不太明白来惧,可以類比為未來/承諾(Future
/Promise)冗栗。未來只是一個只讀的占位符(A Future is a read-only placeholder),就像Signal/SignalProducer和Observable供搀。另外一方面隅居,對于未來的承諾確可以手動自由的實現(xiàn),就像pipe()和Subject葛虐。

Schedulers

這個部分兩個框架都很類似胎源,同樣的概念。但是RAC是連續(xù)的屿脐,串行涕蚤,Rx可以支持并發(fā)。

Composition

合成(Composition)是響應式編程的主要特點的诵。合成成流都是兩個框架的核心万栅,在Rx中也稱作sequences
在Rx中所有observable的實體的類型都是<code>ObservableType</code>西疤,所以我們可以輕松的用同一個操作符將Subject和Observable的實例組合(compose)起來烦粒。
在RAC中,Signal和SignalProducer是兩種不同的對象代赁。我們必須把SignalProducer轉換成Signal后才能compose由Signal實例產(chǎn)生的信號扰她。這兩個對象擁有各自的操作符。所以當你需要混合使用它們時芭碍,你必須考慮到某種操作符是否是兩者通用徒役,這個時候你也不必關心冷/熱的處理了。

關于這個部分豁跑, Colin Eberhardt 很好的總結了:
現(xiàn)在signal的API主要關注在處理‘next’上廉涕,讓你可以改變值泻云,skip, delay, combine并且在不同的線程里觀察值艇拍。signal producer的API主要處理信號的生命周期事件(completed, error)狐蜕,和一些這樣的操作:then, flatMap, takeUntil 和catch。

其他

在RAC中還有<code>Action</code>和<code> Property </code>的概念卸夕。前者是一種處理副作用的類型层释,主要和用戶交互相關。后者用于觀察當執(zhí)行了一個任務后值改變了的情況快集。在Rx中<code>Action</code>也會轉變(translate)成一個<code> Observable </code>類型贡羔。這在RxCocoa中有很好的體現(xiàn),一個集成了Rx基本元素后用于iOS和Mac平臺个初。RAC中的<code> Property </code>可以對應于Rx中的<code> Variable </code>或者<code> BehaviourSubject </code>乖寒。
明白<code> Property </code>/<code> Variable </code>是我們連接必然世界和聲明本質的響應式編程的的橋梁(bridge the imperative world to the declarative nature of Reactive Programming),所以當我們處理一些第三方庫或者iOS/Mac中的核心功能(functionalities)時院溺,<code> Property </code>/<code> Variable </code>有時是基礎楣嘁。

結論

RAC和Rx可以說是兩種完全不同的物種,前者在Cocoa里有著長的歷史和大量的參與者珍逸,后者很年輕逐虚,但是依靠著已經(jīng)在其他語言里像java、js或者C#被驗證過的有效理念谆膳。關于選誰比較好還是要考慮到自己的情況叭爱。RAC認為把觀察的對象區(qū)分為熱/冷是非常有必要的,并且這也是他們框架的一個核心特點漱病。Rx則認為把這個統(tǒng)一為一種對象更好买雾。再次說明,這影響的只是怎么處理訂閱后的副作用杨帽。
RAC 3.0 在為了區(qū)分觀察時的熱/冷狀態(tài)還引入了意料之外的復雜度凝果,比如中斷的概念,區(qū)分兩種對象間不同的操作睦尽,引入一些必要行為(imperative behaviour)比如<code>start</code>是開始產(chǎn)生信號器净。對于一些人來說,這些東西很好甚至是一個殺手級功能当凡,對于另外一些人而言會覺得這個并沒有必要甚至有些危險山害。另外需要記住的一點是RAC一直努力和Cocoa的慣例盡量保持一致,如果你是一個資深的Cocoa開發(fā)者沿量,你在使用RAC應該會覺得比Rx更順手浪慌。
Rx中所有的對象都是observables。好的一件事是朴则,是Reactive Extensions中的一員权纤。從RxJS, RxJava 或者 Rx.Net中遷移過來是一件非常簡單的事,所有概念都是一樣的。這也讓解決問題時會很有趣汹想,因為你現(xiàn)在面臨的問題外邓,可能在RxJava中已經(jīng)有人寫過解決方案,你可以直接拿過來按照當前平臺實現(xiàn)就可以古掏。
這兩個應該選哪一個關鍵看使用習慣损话,從一個客觀的角度來說無法分辨出誰更好。最好的方式是打開Xcode槽唾,都試著使用這兩個框架丧枪,看看那個用起來比較順手。他們都是相同編程理念的實現(xiàn)庞萍,嘗試達到同一個目的:使開發(fā)軟件變得簡單(simplifying software development)拧烦。

歡迎關注我的微博:@沒故事的卓同學

相關鏈接:
函數(shù)式反應型編程(FRP) —— 實時互動應用開發(fā)的新思路
C語言里的side effect是什么意思?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末钝计,一起剝皮案震驚了整個濱河市恋博,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌葵蒂,老刑警劉巖交播,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異践付,居然都是意外死亡秦士,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門永高,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隧土,“玉大人,你說我怎么就攤上這事命爬〔芸” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵饲宛,是天一觀的道長皆愉。 經(jīng)常有香客問我,道長艇抠,這世上最難降的妖魔是什么幕庐? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮家淤,結果婚禮上异剥,老公的妹妹穿的比我還像新娘。我一直安慰自己絮重,他們只是感情好冤寿,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布歹苦。 她就那樣靜靜地躺著,像睡著了一般督怜。 火紅的嫁衣襯著肌膚如雪殴瘦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天亮蛔,我揣著相機與錄音痴施,去河邊找鬼擎厢。 笑死究流,一個胖子當著我的面吹牛,可吹牛的內容都是我干的动遭。 我是一名探鬼主播芬探,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厘惦!你這毒婦竟也來了偷仿?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤宵蕉,失蹤者是張志新(化名)和其女友劉穎酝静,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羡玛,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡别智,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了稼稿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薄榛。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖让歼,靈堂內的尸體忽然破棺而出敞恋,到底是詐尸還是另有隱情,我是刑警寧澤谋右,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布硬猫,位于F島的核電站,受9級特大地震影響改执,放射性物質發(fā)生泄漏啸蜜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一天梧、第九天 我趴在偏房一處隱蔽的房頂上張望盔性。 院中可真熱鬧,春花似錦呢岗、人聲如沸冕香。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悉尾。三九已至突那,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間构眯,已是汗流浹背愕难。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惫霸,地道東北人猫缭。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像壹店,于是被迫代替她去往敵國和親猜丹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容