Swift 響應(yīng)式編程

譯者:李鑫

原文:REACTIVE PROGRAMMING IN SWIFT

本文為極客學(xué)院Wiki組織翻譯,轉(zhuǎn)載請(qǐng)注明出處趁蕊。

時(shí)間:2016.3.4

本文將介紹一個(gè)響應(yīng)式編程架構(gòu) RxSwift槐壳,并結(jié)合使用 Swift 的函數(shù)式功能來編寫更簡潔然低、更表現(xiàn)力的代碼,從而管理應(yīng)用狀態(tài)及并行任務(wù)务唐。

Swift 及其函數(shù)式功能

Swift 可被認(rèn)為是一種現(xiàn)代的面向?qū)ο笳Z言雳攘,對(duì)泛型編程有著原生支持。雖然它不是一種函數(shù)式語言枫笛,但其中的一些特性卻可以讓我們利用函數(shù)式方式來編程吨灭,比如可以利用閉包first-class 類型函數(shù)刑巧,以及不可變的value 類型喧兄。

然而,Cocoa Touch 是一個(gè)面向?qū)ο蟮募軜?gòu)啊楚,有著這一范式所強(qiáng)制的約束吠冤。軟件開發(fā)中常見的問題在于如何管理共享應(yīng)用狀態(tài)以及異步數(shù)據(jù)的并行任務(wù)。

函數(shù)式編程解決這些問題的辦法是恭理,賦予不可變狀態(tài)一定的特權(quán)拯辙,以及將應(yīng)用邏輯定義為不會(huì)在應(yīng)用生存周期內(nèi)改變的表達(dá)式。通過定義自包含的函數(shù)颜价,并行化計(jì)算就會(huì)變得簡單薄风,最大程度減少并發(fā)問題。

響應(yīng)式模型

響應(yīng)式編程根源于 FRP(函數(shù)響應(yīng)式編程)命令驅(qū)動(dòng)的編程方式拍嵌,是以異步數(shù)據(jù)流的形式進(jìn)行編程。

這可能有些難懂循诉,所以最好通過一個(gè)簡單的例子來大體了解一下横辆。

表達(dá)一個(gè)變量間關(guān)系

假如有 2 個(gè)變量(A 和 B),它們的值會(huì)在應(yīng)用運(yùn)行時(shí)中經(jīng)常改變。還有一個(gè)變量(C)狈蚤,它的值取決于前兩個(gè)變量值困肩。

2. var B = 20
3. let C = A * 2 + B
4. 
5. // 當(dāng)前值
6. // A = 10, B = 20, C = 40
7. 
8. A = 0
9.
10. // 當(dāng)前值
11. // A = 0, B = 20, C = 40  

C 值與 A 和 B 有關(guān),B 只被當(dāng) A 和 B 的賦值操作執(zhí)行后脆侮,它們?nèi)咧g的關(guān)系很快就解散了锌畸。這時(shí)再改變 A 與 B 的值,將不會(huì)對(duì) C 的值有任何影響靖避。

所以潭枣,在任何指定時(shí)間,要想計(jì)算表達(dá)式幻捏,就必須根據(jù) A 和 B 的當(dāng)前值盆犁,重新指定 C 值,重新計(jì)算篡九。

用響應(yīng)式編程方式該怎么做呢谐岁?

采用響應(yīng)式模式,我們將創(chuàng)建兩個(gè)流榛臼,來傳遞 A 或 B 值的改變伊佃。

一般可使用彈珠圖來展示這個(gè)原理。如下圖所示沛善,每一行表示連續(xù)的一段時(shí)間航揉,每一個(gè)彈珠表示發(fā)生在特定時(shí)刻的一個(gè)事件。

彈珠圖
彈珠圖

Cocoa Touch 中的做法

在 Cocoa Touch 中路呜,使用鍵值對(duì)觀察迷捧,為發(fā)生改變的變量添加觀察者,當(dāng) KVO 系統(tǒng)通知時(shí)再進(jìn)行處理胀葱。

self.addObserver(self, forKeyPath:"valueA", options: .New, context: nil)
self.addObserver(self, forKeyPath:"valueB", options: .New, context: nil)
 
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    let C = valueA * 2 + valueB
}

如果變量與用戶界面相連漠秋,那么可以在 UIKit 中定義一個(gè)當(dāng)觸發(fā)變化事件時(shí)即被調(diào)用的處理器:

sliderA.addTarget(self, action: "update", forControlEvents: UIControlEvents.ValueChanged)
sliderB.addTarget(self, action: "update", forControlEvents: UIControlEvents.ValueChanged)

func update() {
    let C = sliderA.value * 2 + sliderB.value
}  

但是,對(duì)于調(diào)用的變量抵屿、它們的生存周期以及改變它們值的事件庆锦,以上兩種方法都沒有定義一種持久、顯式的關(guān)系轧葛。

我們可以用響應(yīng)式編程模式來處理這種情況搂抒。當(dāng)前對(duì)于 OS X 和 iOS 開發(fā)者而言,有多種不同的實(shí)現(xiàn)尿扯,比如 RxSwiftReactiveCocoa求晶。

下面簡單介紹一下 RxSwift,不過這兩種架構(gòu)的概念是相似的衷笋。

RxSwift

RxSwift 繼承自觀察者模式芳杏,模擬 Cocoa Touch 對(duì)象中的異步數(shù)據(jù)流,按通常的集合來看待這些對(duì)象。通過利用可觀測流繼承一些 Cocoa Touch 類爵赵,可以訂閱它們的輸出吝秕,并利用復(fù)合運(yùn)算(如 filter()merge()空幻、map()reduce() 等)來使用這些輸出烁峭。

還回到剛才的例子中,假設(shè)一個(gè) iOS 應(yīng)用有兩個(gè)滑塊(sliderA 和 sliderB)秕铛,并希望利用之前的表達(dá)式(A * 2 + B)不斷更新標(biāo)簽(labelC)的值:

1. combineLatest(sliderA.rx_value, sliderB.rx_value) {
2.      $0 * 2 + $1
3. }.map {
4.      "Sum of slider values is \($0)"
5.  }.bindTo(labelC.rx_text)

利用 UISlider 類的 rx_value 后綴约郁,將滑塊的值屬性轉(zhuǎn)化為可觀測類型,
通過在每個(gè)滑塊的可觀測類型上使用 combineLatest() 操作如捅,我們還創(chuàng)建了一種新的可觀測類型棍现,只要其中任何一個(gè)源流釋放出一個(gè)項(xiàng)目,它就會(huì)釋放項(xiàng)目镜遣。結(jié)果就是一個(gè)元組己肮,每個(gè)滑塊值都可以通過操作回調(diào)而轉(zhuǎn)換(代碼行 2)。然后將變換值映射到信息性字符串(代碼行 4)悲关,并將其值綁定到標(biāo)簽上(代碼行 5)谎僻。

通過組合 3 個(gè)獨(dú)立的操作(combineLatest()map()寓辱、bindTo())艘绍,我們就能精確地表達(dá)三種對(duì)象之間的關(guān)系并不斷更新應(yīng)用的 UI,響應(yīng)應(yīng)用狀態(tài)中的改變秫筏。

Sum_of_slider_values
Sum_of_slider_values

額外介紹

上面的內(nèi)容只是對(duì) RxSwift 用途做了一個(gè)粗淺的介紹诱鞠。

參看樣例代碼,在這個(gè)例子中这敬,使用可鏈接的異步任務(wù)下載在線資源航夺。如果這篇文章引發(fā)了你的好奇心,一定要看看這個(gè)例子崔涂。

然后阳掐,可以讀讀這篇文檔,學(xué)習(xí)其他一些 API 擴(kuò)展冷蚂,采用一種函數(shù)式并具有表現(xiàn)力的方式來開發(fā) iOS 應(yīng)用缭保。

還可閱讀 使用輕量級(jí)模式 來了解Swift 模式如何幫助你處理大量相似對(duì)象。

作者簡介

Milton Moura(@mgcm)是一位葡萄牙的自由 iOS 開發(fā)者蝙茶。他曾就職于涉及航空艺骂、電信、能源等領(lǐng)域的多家公司隆夯,如今全心致力于使用蘋果技術(shù)開發(fā)優(yōu)秀應(yīng)用彻亲。除了醉心于設(shè)計(jì)與用戶交互外孕锄,他還非常喜歡新的軟件開發(fā)方式。其博客為:http://defaultbreak.com苞尝。

原文鏈接:http://wiki.jikexueyuan.com/project/geekdigest/Swift-reactive-programming.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宦芦,隨后出現(xiàn)的幾起案子宙址,更是在濱河造成了極大的恐慌,老刑警劉巖调卑,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抡砂,死亡現(xiàn)場離奇詭異,居然都是意外死亡恬涧,警方通過查閱死者的電腦和手機(jī)注益,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溯捆,“玉大人丑搔,你說我怎么就攤上這事√嶙幔” “怎么了啤月?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長劳跃。 經(jīng)常有香客問我谎仲,道長,這世上最難降的妖魔是什么刨仑? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任郑诺,我火速辦了婚禮,結(jié)果婚禮上杉武,老公的妹妹穿的比我還像新娘辙诞。我一直安慰自己,他們只是感情好艺智,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布倘要。 她就那樣靜靜地躺著,像睡著了一般十拣。 火紅的嫁衣襯著肌膚如雪封拧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天夭问,我揣著相機(jī)與錄音泽西,去河邊找鬼。 笑死缰趋,一個(gè)胖子當(dāng)著我的面吹牛捧杉,可吹牛的內(nèi)容都是我干的陕见。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼味抖,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼评甜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仔涩,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤忍坷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后熔脂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佩研,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年霞揉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旬薯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡适秩,死狀恐怖绊序,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情隶症,我是刑警寧澤政模,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站蚂会,受9級(jí)特大地震影響淋样,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胁住,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一趁猴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧彪见,春花似錦儡司、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酵镜,卻和暖如春碉碉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淮韭。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工垢粮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人靠粪。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓蜡吧,卻偏偏與公主長得像毫蚓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子昔善,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫元潘、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,059評(píng)論 4 62
  • 本篇文章簡單記錄了關(guān)于Web會(huì)話管理技術(shù)的學(xué)習(xí)筆記耀鸦。目前常用的會(huì)話管理技術(shù)是Cookie與SessionCooki...
    xiseven閱讀 328評(píng)論 1 2
  • 栗子姑涼突然跑來跟我說:“今晚他約核桃吃晚飯核桃答應(yīng)了”我玩笑著說著核桃肯定也喜歡她袖订,她說:“沒有,是因?yàn)楹颂規(guī)退?..
    季珊嘻嘻閱讀 413評(píng)論 0 0
  • 今天一天沒理你 你也沒找我 早安之后兩個(gè)就沒聯(lián)系了 雖然好想和你說句話 卻還是忍著了 我也不知道為什么 反正...
    小氣鬼丶Sue閱讀 168評(píng)論 0 1
  • 前一陣子嗅虏,我表弟要我?guī)退薷囊幌潞啔v洛姑。看了簡歷皮服,我倒吸了一口涼氣楞艾。一張粗制濫造的word表格,寥寥幾行龄广,信息...
    清蒸閱讀 284評(píng)論 0 0